软键盘,在Windows系统上叫屏幕键盘。前一句只是为了让更多的人通过搜索引擎搜到我的文章。对于实现软键盘,我在网上查找了2、3天。发现用Qt实现并不好缺点很多,所以最终选择用Windows API实现。对此我想说以下几点:

  1. 最好不要用Qt的QApplication::sendEvent或QApplication::postEvent,它们的限制很多。据我粗略测试,它们只对本程序有效。换其它应用程序会影响其它程序的输入焦点,并且不能发送键盘事件。
  2. 获取输入焦点窗口不能用GetForegroundWindow,它获取的是前台主窗口的句柄,并不是窗口内的编辑框句柄。GetFocus也不行。只能用GetGUIThreadInfo获取输入焦点控件句柄。
  3. 模拟按键不要用SendMessage或PostMessage,这俩确实能发送按键消息,但是不支持输入法。根据我的测试连组合键(比如发送Shift+A,模拟输入大写的A)都模拟不了。要使用SendInput模拟发送按键消息,这个能发组合键,也支持输入法。该函数取代了旧的keybd_event函数。
  4. Windows系统的窗口风格WS_EX_NOACTIVATE是相对于其它exe而言的,不会夺取其它程序窗口的焦点。如果另一个窗口跟它在同一个进程内,点击它同样会夺取焦点。

附:

下面是程序的效果图。界面没有美化,直接用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>&lt;-</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>

 

原文地址:http://www.cnblogs.com/mengxiangdu/p/16926418.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性