添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode . Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).

I am trying to write a code for virtual keyboard in PyQt5 . Here is my code.

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class InputState:
    LOWER = 0
    CAPITAL = 1
class KeyButton(QPushButton):
    sigKeyButtonClicked = pyqtSignal()
    def __init__(self, key):
        super(KeyButton, self).__init__()
        self._key = key
        self._activeSize = QSize(50,50)
        self.clicked.connect(self.emitKey)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
    def emitKey(self):
        self.sigKeyButtonClicked.emit()
    def enterEvent(self, event):
        self.setFixedSize(self._activeSize)
    def leaveEvent(self, event):
        self.setFixedSize(self.sizeHint())
    def sizeHint(self):
        return QSize(40, 40)
class VirtualKeyboard(QWidget):
    sigInputString = pyqtSignal()
    sigKeyButtonClicked = pyqtSignal()
    def __init__(self):
        super(VirtualKeyboard, self).__init__()
        self.globalLayout = QVBoxLayout(self)
        self.keysLayout = QGridLayout()
        self.buttonLayout = QHBoxLayout()
        self.keyListByLines = [
                    ['a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
                    ['q', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm'],
                    ['w', 'x', 'c', 'v', 'b', 'n', '_', '.', '/', ' '],
        self.inputString = ""
        self.state = InputState.LOWER
        self.stateButton = QPushButton()
        self.stateButton.setText('Maj.')
        self.backButton = QPushButton()
        self.backButton.setText('<-')
        self.okButton = QPushButton()
        self.okButton.setText('OK')
        self.cancelButton = QPushButton()
        self.cancelButton.setText("Cancel")
        self.inputLine = QLineEdit()
        for lineIndex, line in enumerate(self.keyListByLines):
            for keyIndex, key in enumerate(line):
                buttonName = "keyButton" + key.capitalize()
                self.__setattr__(buttonName, KeyButton(key))
                self.keysLayout.addWidget(self.getButtonByKey(key), self.keyListByLines.index(line), line.index(key))
                self.getButtonByKey(key).setText(key)
                self.getButtonByKey(key).sigKeyButtonClicked.connect(self.addInputByKey)
                self.keysLayout.setColumnMinimumWidth(keyIndex, 50)
            self.keysLayout.setRowMinimumHeight(lineIndex, 50)
        self.stateButton.clicked.connect(self.switchState)
        self.backButton.clicked.connect(self.backspace)
        self.okButton.clicked.connect(self.emitInputString) 
        self.cancelButton.clicked.connect(self.emitCancel)
        self.buttonLayout.addWidget(self.cancelButton)
        self.buttonLayout.addWidget(self.backButton)
        self.buttonLayout.addWidget(self.stateButton)
        self.buttonLayout.addWidget(self.okButton)
        self.globalLayout.addWidget(self.inputLine)
        self.globalLayout.addLayout(self.keysLayout)
        self.globalLayout.addLayout(self.buttonLayout)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
    def getButtonByKey(self, key):
        return getattr(self, "keyButton" + key.capitalize())
    def getLineForButtonByKey(self, key):
        return [key in keyList for keyList in self.keyListByLines].index(True)
    def switchState(self):
        self.state = not self.state
    def addInputByKey(self, key):
        self.inputString += (key.lower(), key.capitalize())[self.state]
        self.inputLine.setText(self.inputString)
    def backspace(self):
        self.inputLine.backspace()
        self.inputString = self.inputString[:-1]
    def emitInputString(self):
        self.sigInputString.emit(self.inputString)
    def emitCancel(self):
        self.sigInputString.emit()
    def sizeHint(self):
        return QSize(480,272)
class Test(QWidget):
    def __init__(self):
        super(Test, self).__init__()
        self.b1 = KeyButton("1")
        self.b2 = KeyButton("2")
        self.b3 = KeyButton("3")
        self.b4 = KeyButton("4")
        self.layout = QGridLayout(self)
        self.layout.addWidget(self.b1,0,0)
        self.layout.addWidget(self.b2,0,1)
        self.layout.addWidget(self.b3,1,0)
        self.layout.addWidget(self.b4,1,1)
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = VirtualKeyboard()
    win.show()
    app.exec_()

I am getting ERROR: TypeError: addInputByKey() missing 1 required positional argument: 'key'

Any help?

@alekssandrap
Hello,

I found your topic because I am looking for a virtual keyboard for my PUQT5 application.
So, I found the problem of your error and this is my solution to solve it (maybe that can help some other people) :

In your pyqtSignal you have to pass an object :
sigKeyButtonClicked = pyqtSignal(object) #line 9

sigInputString = pyqtSignal(object) #line 32
sigKeyButtonClicked = pyqtSignal(object) #line 33

Then you have just to pass your key and your inputString in the signal emit :
self.sigKeyButtonClicked.emit(self._key) #line 20

self.sigInputString.emit("") #line111 in function Cancel in order to avoid an other error

Don't modify line 71 with lambda as @AlfredoC suggest because you won't be able to get the key pressed.

That's all :)

Hope that can help someone else.

Have a great day

Hay i saw your keyboard its really good, i also want to design this kind of keyboard, can you please tell me when i move the cursor on the keys it automatically enlarge. how is it possible ?

and another one is, when i am typing it does not show anything but my only cursor move forward.