多語言按鍵映射校驗demo

  • 實現(xiàn)不同語種通過輸入法上屏后與預期上屏內容結果對比
流程.png

一 焊刹、測試數(shù)據(jù)集收集

test_data.py:通過https://www.cnblogs.com/yiven/p/7118056.html收集物理鍵盤各按鍵對應的映射碼,根據(jù)需要存放test_data.py文件窘疮,各語種均基于物理鍵盤的四排按鍵操作,所以每個測試數(shù)據(jù)中均分為四套數(shù)據(jù)丐吓。

  • 默認按鍵映射碼

僅做最終數(shù)據(jù)對比娄徊,獲取某個按鍵對比結果時候正確。

    def default_data(self):
        '''默認按鍵映射碼'''
        data = {
                '`~': '192', '1!': '49', '2@': '50', '3#': '51', '4$': '52', '5%': '53', '6^': '54', '7&': '55',
                '8*': '56', '9(': '57','0)': '48', '-_': '189', '=+': '187',
                # 中文二排鍵盤
                'q': '81', 'w': '87', 'e': '69', 'r': '82', 't': '84', 'y': '89', 'u': '85', 'i': '73', 'o': '79',
                'p': '80', '[{':'219',']}':'221','|':'220',
                # 中文三排鍵盤
                'a': '65', 's': '83', 'd': '68', 'f': '70', 'g': '71', 'h': '72', 'j': '74', 'k': '75', 'l': '76',
                ';:': '186','’“':'222',
                # 中文四排鍵盤
                'z': '90', 'x': '88', 'c': '67', 'v': '86', 'b': '66', 'n': '78', 'm': '77',',<':'188','.>':'190','/?':'191',
            }
        return data 
  • 測試數(shù)據(jù)映射碼:韓語

四排按鍵對應的直接輸入結果雏掠、按shift+按鍵輸入結果斩祭、開啟capslock+按鍵輸入結果

    def hy(self):
        '''韓語按鍵映射碼'''
        # 韓語第一排按鍵   [直接點擊,開啟shift點擊乡话,開啟capslock點擊]
        list1 = [
            {'`': '192', '1': '49', '2': '50', '3': '51', '4': '52', '5': '53', '6': '54', '7': '55', '8': '56', '9': '57', '0': '48', '-': '189', '=': '187', },
            {'~': '192', '!': '49', '@': '50', '#': '51', '$': '52', '%': '53', '^': '54', '&': '55', '*': '56', '(': '57', ')': '48', '_': '189', '+': '187', },
            {'`': '192', '1': '49', '2': '50', '3': '51', '4': '52', '5': '53', '6': '54', '7': '55', '8': '56', '9': '57', '0': '48', '-': '189', '=': '187', },
        ]
        # 韓語第二排按鍵
        list2 = [
            {'?': '81', '?': '87', '?': '69', '?': '82', '?': '84', '?': '89', '?': '85', '?': '73', '?': '79', '?': '80', },
            {'?': '81', '?': '87', '?': '69', '?': '82', '?': '84', '?': '89', '?': '85', '?': '73', '?': '79', '?': '80', },
            {'?': '81', '?': '87', '?': '69', '?': '82', '?': '84', '?': '89', '?': '85', '?': '73', '?': '79', '?': '80', },
        ]
        # 韓語第三排按鍵
        list3 = [
            {'?': '65', '?': '83', '?': '68', '?': '70', '?': '71', '?': '72', '?': '74', '?': '75', '?': '76', },
            {'?': '65', '?': '83', '?': '68', '?': '70', '?': '71', '?': '72', '?': '74', '?': '75', '?': '76', },
            {'?': '65', '?': '83', '?': '68', '?': '70', '?': '71', '?': '72', '?': '74', '?': '75', '?': '76', },
        ]
        # 韓語第四排按鍵
        list4 = [
            {'?': '90', '?': '88', '?': '67', '?': '86', '?': '66', '?': '78', '?': '77', },
            {'?': '90', '?': '88', '?': '67', '?': '86', '?': '66', '?': '78', '?': '77', },
            {'?': '90', '?': '88', '?': '67', '?': '86', '?': '66', '?': '78', '?': '77', },
        ]
        return list1, list2, list3, list4

二 摧玫、 文件處理

1.打開一個xx.txt文件輸入窗口,可通過subprocess庫完成

subprocess.Popen('ceshi.txt',shell=True)

2.刪除與保存文件內容绑青,刪除與保存均在同一文件內操作诬像,避免重復開啟關閉文件,使用pynput調用快捷鍵映射碼處理

import pynput,time
class Handle_txt():
    def __init__(self):
        self.ctr = pynput.keyboard.Controller()

    def save_data(self):
        '''保存模塊:正序 按下ctrl s 按鍵列表'''
        with self.ctr.pressed(pynput.keyboard.KeyCode.from_vk(17),
                              pynput.keyboard.KeyCode.from_vk(83)):
            pass
        # 逆序 釋放按鍵列表
        with self.ctr.pressed(pynput.keyboard.Key.esc):
            pass

    def clear_data(self):
        '''清空模塊:正序 按下ctrl a  backspace 按鍵列表'''
        with self.ctr.pressed(pynput.keyboard.KeyCode.from_vk(17),
                              pynput.keyboard.KeyCode.from_vk(65),
                              pynput.keyboard.KeyCode.from_vk(8)):
            pass

        time.sleep(0.5)
        # 逆序 釋放按鍵列表
        with self.ctr.pressed(pynput.keyboard.Key.esc):
            pass

三 闸婴、 獲取測試數(shù)據(jù)集

  1. ini配置文件
  • 根據(jù)語種坏挠、按鍵布局及上屏方式編輯配置文件 [sectio] > key = values
;測試語言種類   0 中文
; 1.0 -> 韓語     2.0 -> 藏語     3.0 ->   日語Romaji     4.0 -> 日語kana
; 3.1:日語hiragana   3.2:日語-f-katakana  3.3:日語-f-aiphanumeric   3.4:日語-h-katakana    3.5:日語-h-aiphanumeric
; 4.1:日語hiragana   4.2:日語-f-katakana  4.3:日語-f-aiphanumeric   4.4:日語-h-katakana    4.5:日語-h-aiphanumeric
[test_data]
language = 0
[model]
hanyu = ['基礎布局','shift布局','capslock布局'],'32'
  • 獲取配置文件內容 configparser

configparser.ConfigParser() 使配置文件生效

class Handle_ini():

    def load_ini(self):
        '''獲取配置文件內容'''
        file_path = BasePath + '/Config/config.ini'
        #使配置文件生效
        cf = configparser.ConfigParser()
        cf.read(file_path,encoding='utf-8')
        return cf

    def get_value(self,key,node=None):
        '''獲取配置文件內具體值'''
        if node == None:
            node = 'TEST'
        cf = self.load_ini()

        try:
            data = cf.get(node,key)
            # logger.info('測試 -> 獲取配置文件的值-成功:node:{} -> key:{} -> data:{}'.format(node,key,data))
        except Exception as e:
            # logger.exception('測試 -> 獲取配置文件的值-失敗,node:{} -> key:{} -> error:{}'.format(node, key,e))
            data = None
        return data

2.獲取被測語種對應的布局及數(shù)據(jù)

HanleIni().get_value('language','test_data') 根據(jù)值判斷當前被測語種
HanleIni().get_value('hanyu','model')獲取被測語種的所有數(shù)據(jù)

def test_data():
    ''' 判斷測試哪種語言 return : 測試數(shù)據(jù)(四排鍵盤) 布局  上屏方式'''
    language = Handle_ini().get_value('language', 'test_data')

    if int(language.split('.')[0]) == 0:
        title = '《中文 字母》數(shù)據(jù)'
        testdata = list(Testdata().china())
        layout = list(ast.literal_eval(Handle_ini().get_value('china', 'model')))[0]
        way = int(list(ast.literal_eval(Handle_ini().get_value('china', 'model')))[1])
        label = False
        return title, testdata, layout, way, label

    elif int(language.split('.')[0]) == 1:
        if int(language.split('.')[1]) == 0:
            title = '《韓語》數(shù)據(jù)'
            # 獲取該語言的測試數(shù)據(jù)
            testdata = list(Testdata().hy())
            # 獲取該語言有幾種布局
            layout = list(ast.literal_eval(Handle_ini().get_value('hanyu', 'model')))[0]
            # 獲取該語言合適的上屏方式
            way = int(list(ast.literal_eval(Handle_ini().get_value('hanyu', 'model')))[1])
            # 特殊處理標識            
            label = False
            return title, testdata, layout, way, label
        else:
            return '錯誤:檢查{0}數(shù)據(jù)是否存在'.format(language)

3.獲取各布局下的測試數(shù)據(jù)

def keyboard(layouts,datas):
    '''  layouts:布局       datas:測試數(shù)據(jù)
        以鍵盤按鍵為基礎:四排按鍵掠拳,分別獲取每個布局下的按鍵數(shù)據(jù)
    '''
    lists = []
    for i in range(len(layouts)):
        list = []
        for data in datas:
            list.append(data[i])
        lists.append(list)
    return lists

四癞揉、獲取到的數(shù)據(jù)進行映射

pynput 支持鼠標和鍵盤輸入和監(jiān)控 。詳細使用見:https://pypi.org/project/pynput/

  • 按下按鍵 pynput.keyboard.Controller().press()
  • 釋放按鍵 pynput.keyboard.Controller().release()
class Keyboard():
    def __init__(self):
        self.ctr = pynput.keyboard.Controller()
        self.num = ''
    def key_mapping(self, layouts, key_list, way, label):

        '''以布局為基礎 傳遞 按鍵參數(shù) 溺欧,發(fā)起按鍵映射'''
        if label == False:
            for layout in layouts:
                print(layout)
                if layout == '基礎布局':
                    # print('*********')
                    for keys in key_list[0]:
                        for key,values in keys.items():
                            self.ctr.press(pynput.keyboard.KeyCode.from_vk(int(values)))
                            self.ctr.release(pynput.keyboard.KeyCode.from_vk(int(values)))

                            self.ctr.press(pynput.keyboard.KeyCode.from_vk(int(way)))
                            self.ctr.release(pynput.keyboard.KeyCode.from_vk(int(way)))

                            self.get_txt(key,values)
                    time.sleep(1)
                elif layout == 'shift布局':
                    # print('*********')
                    for keys in key_list[1]:
                        for key,values in keys.items():
                            self.ctr.press(pynput.keyboard.KeyCode.from_vk(16))
                            self.ctr.press(pynput.keyboard.KeyCode.from_vk(int(values)))
                            self.ctr.release(pynput.keyboard.KeyCode.from_vk(int(values)))
                            self.ctr.release(pynput.keyboard.KeyCode.from_vk(16))

                            self.ctr.press(pynput.keyboard.KeyCode.from_vk(int(way)))
                            self.ctr.release(pynput.keyboard.KeyCode.from_vk(int(way)))

                            self.get_txt(key,values)
                    time.sleep(1)
                elif layout == 'capslock布局':
                    # print('*********')
                    '''
                    先開啟caps喊熟,按下每個按鍵保存對比,全部按鍵執(zhí)行完畢后姐刁,釋放caps
                    '''
                    self.ctr.press(pynput.keyboard.KeyCode.from_vk(20))
                    for keys in key_list[2]:
                        for key,values in keys.items():
                            self.ctr.press(pynput.keyboard.KeyCode.from_vk(int(values)))
                            self.ctr.release(pynput.keyboard.KeyCode.from_vk(int(values)))

                            self.ctr.press(pynput.keyboard.KeyCode.from_vk(int(way)))
                            self.ctr.release(pynput.keyboard.KeyCode.from_vk(int(way)))

                            self.get_txt(key, values)

                    self.ctr.release(pynput.keyboard.KeyCode.from_vk(20))
                    time.sleep(1)
                else:
                    logger.error('當前布局類型錯誤:{0}'.format(list(layout.keys())))
                    break
                time.sleep(1)    

五芥牌、結果對比

1.按鍵輸入內容后,保存獲取文本內容聂使;
2.如果韓語某按鍵預期結果與文本內容一致壁拉,則通過;
3.若果韓語某按鍵預期結果與文本內容不一致柏靶,則獲取該按鍵對應鍵值對的值弃理,獲取default數(shù)據(jù)中鍵盤的按鍵,返回失敗屎蜓。

    def get_txt(self,key,values):
        '''獲取文件內容痘昌,進行比對校驗'''
        Handle_txt().save_data()
        Handle_txt().clear_data()
        with open('ceshi.txt','r',encoding='utf-8') as f:
            data = f.read()
            default = Testdata().default_data()
            if key == data.split(' ')[0]:
                i = [i for i, j in default.items() if values == j]
                print('鍵盤:{0} 鍵映射正常:預期結果:{1} -> 實際結果{2}'.format(i,key,data))
                # logger.info('鍵盤:{0} 鍵映射正常:預期結果:{1} -> 實際結果{2}'.format(i,key,data))

            else:
                i= [i for i, j in default.items() if values == j]
                logger.error('鍵盤{0} 鍵映射異常:預期結果{1} -> 實際結果{2}'.format(i, key, data))

六、問題小結

  • ※※ 使用pynput的.press模擬按下按鍵后炬转,必須有對應的.release將該按鍵給釋放掉辆苔,不然會出現(xiàn)異常。
  • ※※ 文件對比:按正常流程扼劈,輸入內容后先保存驻啤,獲取文本內容進行對比,最后清除文件內容荐吵,獲取的結果是不正確的骑冗。必須先保存赊瞬,再清除,最后獲取文件內容進行對比沐旨。
  • ※※ 因使用pynput庫的原因森逮,造成在linux系統(tǒng)運行該腳本,存在報錯:X11lib
    答:初步判斷是因為.press(pynput.keyboard.KeyCode.from_vk(16))16對應的shift按鍵磁携,這種特殊的功能按鍵使用映射碼直接調用影響褒侧,所以出錯。解決辦法:監(jiān)聽鍵盤shift按鍵名稱為:shift_l 所以使用.press(pynput.keyboard.Key.shift_l)避免谊迄。注:待校驗闷供。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市统诺,隨后出現(xiàn)的幾起案子歪脏,更是在濱河造成了極大的恐慌,老刑警劉巖粮呢,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件婿失,死亡現(xiàn)場離奇詭異,居然都是意外死亡啄寡,警方通過查閱死者的電腦和手機豪硅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挺物,“玉大人懒浮,你說我怎么就攤上這事∈短伲” “怎么了砚著?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長痴昧。 經常有香客問我稽穆,道長,這世上最難降的妖魔是什么赶撰? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任舌镶,我火速辦了婚禮,結果婚禮上扣囊,老公的妹妹穿的比我還像新娘乎折。我一直安慰自己绒疗,他們只是感情好侵歇,可當我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吓蘑,像睡著了一般惕虑。 火紅的嫁衣襯著肌膚如雪坟冲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天溃蔫,我揣著相機與錄音健提,去河邊找鬼。 笑死伟叛,一個胖子當著我的面吹牛私痹,可吹牛的內容都是我干的。 我是一名探鬼主播统刮,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼紊遵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了侥蒙?” 一聲冷哼從身側響起暗膜,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鞭衩,沒想到半個月后学搜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡论衍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年瑞佩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饲齐。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡钉凌,死狀恐怖,靈堂內的尸體忽然破棺而出捂人,到底是詐尸還是另有隱情御雕,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布滥搭,位于F島的核電站酸纲,受9級特大地震影響,放射性物質發(fā)生泄漏瑟匆。R本人自食惡果不足惜闽坡,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望愁溜。 院中可真熱鬧疾嗅,春花似錦、人聲如沸冕象。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渐扮。三九已至论悴,卻和暖如春掖棉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背膀估。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工幔亥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人察纯。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓帕棉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饼记。 傳聞我的和親對象是個殘疾皇子笤昨,可洞房花燭夜當晚...
    茶點故事閱讀 43,666評論 2 350

推薦閱讀更多精彩內容