软键盘,在Windows系统上叫屏幕键盘。前一句只是为了让更多的人通过搜索引擎搜到我的文章。对于实现软键盘,我在网上查找了2、3天。发现用Qt实现并不好缺点很多,所以最终选择用Windows API实现。对此我想说以下几点:
- 最好不要用Qt的QApplication::sendEvent或QApplication::postEvent,它们的限制很多。据我粗略测试,它们只对本程序有效。换其它应用程序会影响其它程序的输入焦点,并且不能发送键盘事件。
- 获取输入焦点窗口不能用GetForegroundWindow,它获取的是前台主窗口的句柄,并不是窗口内的编辑框句柄。GetFocus也不行。只能用GetGUIThreadInfo获取输入焦点控件句柄。
- 模拟按键不要用SendMessage或PostMessage,这俩确实能发送按键消息,但是不支持输入法。根据我的测试连组合键(比如发送Shift+A,模拟输入大写的A)都模拟不了。要使用SendInput模拟发送按键消息,这个能发组合键,也支持输入法。该函数取代了旧的keybd_event函数。
- Windows系统的窗口风格WS_EX_NOACTIVATE是相对于其它exe而言的,不会夺取其它程序窗口的焦点。如果另一个窗口跟它在同一个进程内,点击它同样会夺取焦点。
附:
- SendMessage或PostMessage模拟发送KeyDown、KeyUp消息参考文件:https://learn.microsoft.com/zh-cn/windows/win32/inputdev/wm-keyup
- SendInput函数的参考文件:https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-sendinput
下面是程序的效果图。界面没有美化,直接用QPushButton做的按钮。读者如果需要可以自己去美化,比如使用qss样式表。我的审美不行而且对qss也不熟悉,做不了漂亮的界面:
上代码,头文件:
class MSoftKeyboard : public QWidget { Q_OBJECT public: MSoftKeyboard(QWidget *parent = Q_NULLPTR); ~MSoftKeyboard() = default; private slots: void buttonClicked(); private: void sendKeyEvent(HWND hWnd, QObject* button); void switchCases(); void initKeyMappingWin(); HWND findFocusWindow(); struct KeyMap { QPushButton* uiCtl; int qtEnum1; /* 小写字母虚拟键盘码 */ int qtEnum2; /* 大写字母虚拟键盘码 */ bool capsSwitch; bool shiftSwitch; QString lowCase; /* 小写字母 */ QString upperCase; /* 大写字母 */ }; private: Ui::MSoftKeyboard ui; QVector<KeyMap> keyMapping; bool capslock; bool shift; };
CPP文件(需要包含Windows头文件:#include "qt_windows.h"):
MSoftKeyboard::MSoftKeyboard(QWidget *parent) : QWidget(parent), capslock(false), shift(false) { ui.setupUi(this); setWindowFlag(Qt::Tool); setWindowFlag(Qt::WindowStaysOnTopHint); HWND hWnd = (HWND)winId(); LONG style = GetWindowLong(hWnd, GWL_EXSTYLE); SetWindowLong(hWnd, GWL_EXSTYLE, style | WS_EX_NOACTIVATE); initKeyMappingWin(); for (const auto& item : keyMapping) { connect(item.uiCtl, &QPushButton::clicked, this, &MSoftKeyboard::buttonClicked); } } void MSoftKeyboard::initKeyMappingWin() { keyMapping.append({ ui.pb0, '0', '0', 0, 1, u8"0", u8")" }); keyMapping.append({ ui.pb1, '1', '1', 0, 1, u8"1", u8"!" }); keyMapping.append({ ui.pb2, '2', '2', 0, 1, u8"2", u8"@" }); keyMapping.append({ ui.pb3, '3', '3', 0, 1, u8"3", u8"#" }); keyMapping.append({ ui.pb4, '4', '4', 0, 1, u8"4", u8"$" }); keyMapping.append({ ui.pb5, '5', '5', 0, 1, u8"5", u8"%" }); keyMapping.append({ ui.pb6, '6', '6', 0, 1, u8"6", u8"^" }); keyMapping.append({ ui.pb7, '7', '7', 0, 1, u8"7", u8"&&" }); keyMapping.append({ ui.pb8, '8', '8', 0, 1, u8"8", u8"*" }); keyMapping.append({ ui.pb9, '9', '9', 0, 1, u8"9", u8"(" }); keyMapping.append({ ui.pba, 'A', 'A', 1, 1, u8"a", u8"A" }); keyMapping.append({ ui.pbb, 'B', 'B', 1, 1, u8"b", u8"B" }); keyMapping.append({ ui.pbc, 'C', 'C', 1, 1, u8"c", u8"C" }); keyMapping.append({ ui.pbd, 'D', 'D', 1, 1, u8"d", u8"D" }); keyMapping.append({ ui.pbe, 'E', 'E', 1, 1, u8"e", u8"E" }); keyMapping.append({ ui.pbf, 'F', 'F', 1, 1, u8"f", u8"F" }); keyMapping.append({ ui.pbg, 'G', 'G', 1, 1, u8"g", u8"G" }); keyMapping.append({ ui.pbh, 'H', 'H', 1, 1, u8"h", u8"H" }); keyMapping.append({ ui.pbi, 'I', 'I', 1, 1, u8"i", u8"I" }); keyMapping.append({ ui.pbj, 'J', 'J', 1, 1, u8"j", u8"J" }); keyMapping.append({ ui.pbk, 'K', 'K', 1, 1, u8"k", u8"K" }); keyMapping.append({ ui.pbl, 'L', 'L', 1, 1, u8"l", u8"L" }); keyMapping.append({ ui.pbm, 'M', 'M', 1, 1, u8"m", u8"M" }); keyMapping.append({ ui.pbn, 'N', 'N', 1, 1, u8"n", u8"N" }); keyMapping.append({ ui.pbo, 'O', 'O', 1, 1, u8"o", u8"O" }); keyMapping.append({ ui.pbp, 'P', 'P', 1, 1, u8"p", u8"P" }); keyMapping.append({ ui.pbq, 'Q', 'Q', 1, 1, u8"q", u8"Q" }); keyMapping.append({ ui.pbr, 'R', 'R', 1, 1, u8"r", u8"R" }); keyMapping.append({ ui.pbs, 'S', 'S', 1, 1, u8"s", u8"S" }); keyMapping.append({ ui.pbt, 'T', 'T', 1, 1, u8"t", u8"T" }); keyMapping.append({ ui.pbu, 'U', 'U', 1, 1, u8"u", u8"U" }); keyMapping.append({ ui.pbv, 'V', 'V', 1, 1, u8"v", u8"V" }); keyMapping.append({ ui.pbw, 'W', 'W', 1, 1, u8"w", u8"W" }); keyMapping.append({ ui.pbx, 'X', 'X', 1, 1, u8"x", u8"X" }); keyMapping.append({ ui.pby, 'Y', 'Y', 1, 1, u8"y", u8"Y" }); keyMapping.append({ ui.pbz, 'Z', 'Z', 1, 1, u8"z", u8"Z" }); keyMapping.append({ ui.pbSpace, VK_SPACE, VK_SPACE, 0, 0, u8" ", u8" " }); keyMapping.append({ ui.pbComma, VK_OEM_COMMA, VK_OEM_COMMA, 0, 1, u8",", u8"<" }); keyMapping.append({ ui.pbDot, VK_OEM_PERIOD, VK_OEM_PERIOD, 0, 1, u8".", u8">" }); keyMapping.append({ ui.pbTab, VK_TAB, VK_TAB, 0, 0, u8"", u8"" }); keyMapping.append({ ui.pbCaps, VK_CAPITAL, VK_CAPITAL, 0, 0, u8"", u8"" }); keyMapping.append({ ui.pbShift, VK_SHIFT, VK_SHIFT, 0, 0, u8"", u8"" }); keyMapping.append({ ui.pbBackspace, VK_BACK, VK_BACK, 0, 0, u8"", u8"" }); keyMapping.append({ ui.pbEnter, VK_RETURN, VK_RETURN, 0, 0, u8"", u8"" }); } void MSoftKeyboard::switchCases() { bool mixedCaps = (shift ^ capslock); for (const auto& item : keyMapping) { if (item.capsSwitch && !item.shiftSwitch) { item.uiCtl->setText(capslock ? item.upperCase : item.lowCase); } if (item.shiftSwitch && !item.capsSwitch) { item.uiCtl->setText(shift ? item.upperCase : item.lowCase); } if (item.shiftSwitch && item.capsSwitch) { item.uiCtl->setText(mixedCaps ? item.upperCase : item.lowCase); } } } HWND MSoftKeyboard::findFocusWindow() { GUITHREADINFO gui = { 0 }; gui.cbSize = sizeof(GUITHREADINFO); GetGUIThreadInfo(0, &gui); return gui.hwndFocus; } void MSoftKeyboard::sendKeyEvent(HWND hWnd, QObject* button) { auto found = std::find_if(keyMapping.begin(), keyMapping.end(), [button](const KeyMap& m) { return m.uiCtl == button; }); if (found != keyMapping.end()) { if (shift) { INPUT inputs[4]; ZeroMemory(inputs, sizeof(inputs)); inputs[0].type = INPUT_KEYBOARD; inputs[0].ki.wVk = VK_SHIFT; inputs[1].type = INPUT_KEYBOARD; inputs[1].ki.wVk = found->qtEnum1; inputs[2].type = INPUT_KEYBOARD; inputs[2].ki.wVk = found->qtEnum1; inputs[2].ki.dwFlags = KEYEVENTF_KEYUP; inputs[3].type = INPUT_KEYBOARD; inputs[3].ki.wVk = VK_SHIFT; inputs[3].ki.dwFlags = KEYEVENTF_KEYUP; SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT)); } else { INPUT inputs[2]; ZeroMemory(inputs, sizeof(inputs)); inputs[0].type = INPUT_KEYBOARD; inputs[0].ki.wVk = found->qtEnum1; inputs[1].type = INPUT_KEYBOARD; inputs[1].ki.wVk = found->qtEnum1; inputs[1].ki.dwFlags = KEYEVENTF_KEYUP; SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT)); } } } void MSoftKeyboard::buttonClicked() { QObject* src = sender(); if (src == ui.pbShift) { shift = !shift; switchCases(); if (shift) { /* 手动松开Shift不返回,继续执行发送Shift点击消息 */ /* 按Shift键可以改变中英文输入 */ return; } } else if (src == ui.pbCaps) { capslock = !capslock; switchCases(); } HWND hWnd = findFocusWindow(); sendKeyEvent(hWnd, src); if (shift) { ui.pbShift->setChecked(false); shift = false; switchCases(); } }
UI文件:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MSoftKeyboard</class> <widget class="QWidget" name="MSoftKeyboard"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>496</width> <height>180</height> </rect> </property> <property name="windowTitle"> <string>屏幕键盘</string> </property> <layout class="QGridLayout" name="gridLayout"> <property name="leftMargin"> <number>2</number> </property> <property name="topMargin"> <number>2</number> </property> <property name="rightMargin"> <number>2</number> </property> <property name="bottomMargin"> <number>2</number> </property> <property name="spacing"> <number>1</number> </property> <item row="0" column="0"> <widget class="QPushButton" name="pb1"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>1</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="1"> <widget class="QPushButton" name="pb2"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>2</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="2"> <widget class="QPushButton" name="pb3"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>3</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="3"> <widget class="QPushButton" name="pb4"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>4</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="4"> <widget class="QPushButton" name="pb5"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>5</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="5"> <widget class="QPushButton" name="pb6"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>6</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="6"> <widget class="QPushButton" name="pb7"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>7</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="7"> <widget class="QPushButton" name="pb8"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>8</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="8"> <widget class="QPushButton" name="pb9"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>9</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="9"> <widget class="QPushButton" name="pb0"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>0</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="0" column="10"> <widget class="QPushButton" name="pbBackspace"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string><-</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="0"> <widget class="QPushButton" name="pbTab"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>Tab</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="1"> <widget class="QPushButton" name="pbq"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>q</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="2"> <widget class="QPushButton" name="pbw"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>w</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="3"> <widget class="QPushButton" name="pbe"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>e</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="4"> <widget class="QPushButton" name="pbr"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>r</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="5"> <widget class="QPushButton" name="pbt"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>t</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="6"> <widget class="QPushButton" name="pby"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>y</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="7"> <widget class="QPushButton" name="pbu"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>u</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="8"> <widget class="QPushButton" name="pbi"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>i</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="9"> <widget class="QPushButton" name="pbo"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>o</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="1" column="10"> <widget class="QPushButton" name="pbp"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>p</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="0"> <widget class="QPushButton" name="pbCaps"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>Caps</string> </property> <property name="checkable"> <bool>true</bool> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="1"> <widget class="QPushButton" name="pba"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>a</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="2"> <widget class="QPushButton" name="pbs"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>s</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="3"> <widget class="QPushButton" name="pbd"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>d</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="4"> <widget class="QPushButton" name="pbf"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>f</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="5"> <widget class="QPushButton" name="pbg"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>g</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="6"> <widget class="QPushButton" name="pbh"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>h</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="7"> <widget class="QPushButton" name="pbj"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>j</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="8"> <widget class="QPushButton" name="pbk"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>k</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="9"> <widget class="QPushButton" name="pbl"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>l</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="2" column="10"> <widget class="QPushButton" name="pbEnter"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>Enter</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="0"> <widget class="QPushButton" name="pbShift"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>Shift</string> </property> <property name="checkable"> <bool>true</bool> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="1"> <widget class="QPushButton" name="pbz"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>z</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="2"> <widget class="QPushButton" name="pbx"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>x</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="3"> <widget class="QPushButton" name="pbc"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>c</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="4"> <widget class="QPushButton" name="pbv"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>v</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="5"> <widget class="QPushButton" name="pbb"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>b</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="6"> <widget class="QPushButton" name="pbn"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>n</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="7"> <widget class="QPushButton" name="pbm"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>m</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="8"> <widget class="QPushButton" name="pbComma"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>,</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="9"> <widget class="QPushButton" name="pbDot"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>.</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> <item row="3" column="10"> <widget class="QPushButton" name="pbSpace"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="minimumSize"> <size> <width>12</width> <height>12</height> </size> </property> <property name="text"> <string>Space</string> </property> <property name="autoRepeat"> <bool>true</bool> </property> </widget> </item> </layout> </widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections/> </ui>
标签:12,Qt,实现,keyMapping,软键盘,ui,true,append,u8 From: https://www.cnblogs.com/mengxiangdu/p/16926418.html