如何使用 Pyqt 小部件创建键盘和鼠标事件

How to create keyboard and mouse events with Pyqt widgets

我刚开始在 Pycharms 中使用 python 3.x 进行 Qt 设计。我看过一个将 .ui 文件转换为 .py 文件的教程。我现在很好。我正在实现一个聊天程序。

现在,我想在 TextEdit、linEdit 中输入,但它不等我输入。我想将键盘或鼠标事件与它们连接,所以当我单击时,它会等待我输入,当我按下 Enter 时,它会存储字符串。

space 和#here 之间的代码是我需要帮助的地方。基本上我想为这些事件定义方法并稍后从中调用它们。

我的Ui_MainWindowclass如下:

class Ui_MainWindow(QtGui.QMainWindow):

    def __init__(self):
        super(Ui_MainWindow,self).__init__()

        self.setObjectName(_fromUtf8("MainWindow"))
        self.resize(611, 487)
        self.setTabShape(QtGui.QTabWidget.Rounded)
        self.centralwidget = QtGui.QWidget(self)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.frame = QtGui.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(10, 30, 591, 41))
        self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtGui.QFrame.Raised)
        self.frame.setObjectName(_fromUtf8("frame"))
        self.label = QtGui.QLabel(self.frame)
        self.label.setGeometry(QtCore.QRect(10, 10, 81, 17))
        self.label.setObjectName(_fromUtf8("label"))
        self.label_2 = QtGui.QLabel(self.frame)
        self.label_2.setGeometry(QtCore.QRect(320, 10, 66, 17))
        self.label_2.setObjectName(_fromUtf8("label_2"))
        #Here
        self.lineEdit = QtGui.QLineEdit(self.frame)
        self.lineEdit.setGeometry(QtCore.QRect(90, 10, 221, 21))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        #Here
        self.lineEdit_3 = QtGui.QLineEdit(self.frame)
        self.lineEdit_3.setGeometry(QtCore.QRect(360, 10, 221, 21))
        self.lineEdit_3.setObjectName(_fromUtf8("lineEdit_3"))

        self.frame_2 = QtGui.QFrame(self.centralwidget)
        self.frame_2.setGeometry(QtCore.QRect(10, 70, 291, 361))
        self.frame_2.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtGui.QFrame.Raised)
        self.frame_2.setObjectName(_fromUtf8("frame_2"))
        #Here
        self.textEdit = QtGui.QTextEdit(self.frame_2)
        self.textEdit.setGeometry(QtCore.QRect(10, 10, 271, 301))
        self.textEdit.setObjectName(_fromUtf8("textEdit"))

        self.pushButton_3 = QtGui.QPushButton(self.frame_2)
        self.pushButton_3.setGeometry(QtCore.QRect(10, 310, 161, 41))
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.pushButton_4 = QtGui.QPushButton(self.frame_2)
        self.pushButton_4.setGeometry(QtCore.QRect(180, 310, 98, 41))
        self.pushButton_4.setObjectName(_fromUtf8("pushButton_4"))
        self.pushButton_4.clicked.connect(self.clrLogs)         # Clear Logs from WidgetList by clicking
        self.verticalScrollBar = QtGui.QScrollBar(self.frame_2)
        self.verticalScrollBar.setGeometry(QtCore.QRect(260, 10, 20, 301))
        self.verticalScrollBar.setMinimumSize(QtCore.QSize(16, 301))
        self.verticalScrollBar.setCursor(QtGui.QCursor(QtCore.Qt.SizeVerCursor))
        self.verticalScrollBar.setAutoFillBackground(False)
        self.verticalScrollBar.setOrientation(QtCore.Qt.Vertical)
        self.verticalScrollBar.setInvertedAppearance(False)
        self.verticalScrollBar.setObjectName(_fromUtf8("verticalScrollBar"))

    ######################################################
        # Scroll to the bottom of chat windows
        # self.textEdit.verticalScrollBar().setValue(self.textEdit.verticalScrollBar().maximum)

        self.frame_3 = QtGui.QFrame(self.centralwidget)
        self.frame_3.setGeometry(QtCore.QRect(300, 70, 301, 361))
        self.frame_3.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame_3.setFrameShadow(QtGui.QFrame.Raised)
        self.frame_3.setObjectName(_fromUtf8("frame_3"))
        self.listWidget = QtGui.QListWidget(self.frame_3)
        self.listWidget.setGeometry(QtCore.QRect(10, 10, 281, 341))
        self.listWidget.setObjectName(_fromUtf8("listWidget"))
        self.verticalScrollBar_2 = QtGui.QScrollBar(self.frame_3)
        self.verticalScrollBar_2.setGeometry(QtCore.QRect(270, 10, 21, 341))
        self.verticalScrollBar_2.setOrientation(QtCore.Qt.Vertical)
        self.verticalScrollBar_2.setObjectName(_fromUtf8("verticalScrollBar_2"))
        self.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(self)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 611, 25))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuMenu_Actions = QtGui.QMenu(self.menubar)
        self.menuMenu_Actions.setObjectName(_fromUtf8("menuMenu_Actions"))
        self.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(self)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        self.setStatusBar(self.statusbar)
        self.actionVersion = QtGui.QAction(self)
        self.actionVersion.setObjectName(_fromUtf8("actionVersion"))
        self.actionVersion.triggered.connect(Chat.app_ver)              # When submenu Action item Version is clicked
        self.actionExit = QtGui.QAction(self)
        self.actionExit.setObjectName(_fromUtf8("actionExit"))
        self.actionExit.triggered.connect(qApp.quit)                    #When submenu Action item Exit is clicked
        self.menuMenu_Actions.addAction(self.actionVersion)
        self.menuMenu_Actions.addAction(self.actionExit)
        self.menubar.addAction(self.menuMenu_Actions.menuAction())
        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", WindowTitle, None))
        self.setWindowIcon(QtGui.QIcon('chat_icon'))
        self.label.setText(_translate("MainWindow", "IP Address:", None))
        self.label_2.setText(_translate("MainWindow", "Nick:", None))
        self.pushButton_3.setText(_translate("MainWindow", "Send SMS", None))
        self.pushButton_4.setText(_translate("MainWindow", "Clear Logs", None))
        self.menuMenu_Actions.setTitle(_translate("MainWindow", "Menu Actions", None))
        self.actionVersion.setText(_translate("MainWindow", "Version", None))
        self.actionExit.setText(_translate("MainWindow", "Exit", None))

    def clrLogs(self):
        self.listWidget.clear()

左边大的是TextEdit,最右边的是listWidget。我想输入 TextEdit 并存储它,然后将此消息发送到 Chatlog(ListWidget)。

我会开始说你必须关心以下事情:

  1. 你的键盘UI,假设是一个小原型。
  2. 注意谁在获取您的键盘焦点。
  3. 照顾好你的过滤器以捕捉你需要的事件。
  4. 从您的键盘向索赔人对象发送正确的回复。

我会在这里向您展示一些我花了相当多的时间做的非常好的例子,还有一个非常简单和小的例子。由于这是相当多的代码,所以我将离开这个 small example and this more complex example from my github.

您可以克隆或复制并粘贴代码,如果您复制和粘贴,请确保它带有正确的导入。

编辑[添加]

这是从您传递的接收器捕获事件并发布等效事件的小示例:

import sys

from PyQt5.QtCore import QCoreApplication
from PyQt5.QtCore import QEvent
from PyQt5.QtCore import Qt
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QWidget

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.central_widget = QWidget()
        self.cw_layout = QHBoxLayout()
        self.central_widget.setLayout(self.cw_layout)
        self.setCentralWidget(self.central_widget)

        self.line = LineEdit()
        self.kb = KeyBoard(self.line)

        self.cw_layout.addWidget(self.line)

        self.create_connections()

    def create_connections(self):
        self.line.signal_evoke_kb.connect(self.show_kb)

    def show_kb(self):
        if self.kb.isHidden():
            self.kb.show()
        else:
            self.kb.hide()


class LineEdit(QLineEdit):

    signal_evoke_kb = pyqtSignal()

    def __init__(self):
        super(LineEdit, self).__init__()

    def mousePressEvent(self, QMouseEvent):
        super(LineEdit, self).mousePressEvent(QMouseEvent)
        self.signal_evoke_kb.emit()

class Key(QPushButton):

    def __init__(self, name, event, receiver):
        super(Key, self).__init__()
        self.name = name
        self.event = event
        self.setText(name)


class KeyBoard(QWidget):

    def __init__(self, receiver):
        super(KeyBoard, self).__init__()
        self.receiver = receiver
        self.layout = QHBoxLayout()
        self.keys = ['q','w','e','r','t','y']
        self.dict_keys ={'q':Qt.Key_Q,'w':Qt.Key_W,'e':Qt.Key_E,'r':Qt.Key_R,'t':Qt.Key_T,'y':Qt.Key_Y,}
        for key in self.keys:
            key_keyboard = Key(key,self.dict_keys[key],receiver)
            key_keyboard.clicked.connect(self.key_pressed)
            self.layout.addWidget(key_keyboard)
        self.setLayout(self.layout)

    def key_pressed(self):
        try:
            event = QKeyEvent(QEvent.KeyPress, self.sender().event, Qt.NoModifier,
                              self.sender().name, False)
            QCoreApplication.postEvent(self.receiver, event)
        except Exception as e:
            print(e)

    def keyPressEvent(self, evt):
        event = QKeyEvent(QEvent.KeyPress, evt.key(), evt.modifiers(),
                          evt.text(), False)
        QCoreApplication.postEvent(self.receiver, event)
        evt.ignore()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())

通过这种方式,您可以个性化您的密钥,因为您拥有自己的密钥,并且在您需要大写和其他所有内容时可以更好地组织它。如果您愿意这样做,我强烈建议您查看我之前链接的更完整的示例。