【问题标题】:How to create keyboard and mouse events with Pyqt widgets如何使用 Pyqt 小部件创建键盘和鼠标事件
【发布时间】:2019-03-04 12:18:46
【问题描述】:

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

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

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

我的 Ui_MainWindow 类如下:

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)。

【问题讨论】:

  • 你可以更好地解释我,你点击的时候是什么意思,你在哪里点击?
  • 我想点击发送短信上方的 TextEdit 小部件。然后,当我单击时,我将开始输入它,直到按下输入
  • 我不懂你,你自己解释清楚。你有 2 个 lineEdits,IP 地址和 Nick
  • 先生,我开始意识到我的愚蠢,这些 lineEdits 是无用的。它们只是用于放置信息。 PS:我已经编辑了我的评论
  • 我的理解是,您想在 QTextEdit 中填充数据,然后按回车键,然后对 QTextEdit 内容执行操作,对吗?

标签: python python-3.x pyqt pycharm pyqt4


【解决方案1】:

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

  1. 您的键盘 UI,假设是一个小型原型。
  2. 注意谁在获取您的键盘焦点。
  3. 注意过滤器以捕获所需的事件。
  4. 从您的键盘向声明对象发送正确的响应。

我会在这里向您展示一些非常好的示例,我已经花费了相当多的时间来做,另一个非常简单和小。由于代码量相当大,我会从my github 留下这个small example 和这个more complex 示例。

您可以克隆或复制和粘贴代码,只要在复制和粘贴时确保它带有正确的导入即可。

已编辑[添加]

这是一个小例子,从你传递的接收者那里捕获事件,并发布等效事件:

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_())

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

【讨论】:

  • 欢迎 Zain ")。如果您想深入了解它,请查看 QT 本身的虚拟键盘,如果您想对其进行个性化设置,您会有些头疼,但它也是一个非常好的选择! :D
  • 先生,我有一个问题。既然我已经做了一个 lineEdit 我该如何连接它,就像你在你的小例子中展示的那样
  • 您好,Zain,我得到了一个小示例并增加了一些功能,看看它是否有意义以及是否是您需要的。刚刚编辑了我的答案")
猜你喜欢
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
相关资源
最近更新 更多