【问题标题】:trying to use 4x4 keypad with pyqt5 gui application尝试将 4x4 键盘与 pyqt5 gui 应用程序一起使用
【发布时间】:2020-02-28 06:49:30
【问题描述】:

我正在尝试使用 pad4pi 模块和基于 pyqt5 的 GUI 应用程序编写从 4x4 键盘(机械)输入的代码。

当我尝试单击按钮时,它可以正常工作,但是当我尝试生成某些事件时,我收到错误消息:

QObject::startTimer: Timers can only be used with threads started with QThread
class DigitalClock(QWidget,QThread):
    def __init__(self):
        super().__init__()
        SetupKeyboard.keypad.registerKeyPressHandler(self.printKey)
        self.setWindowTitle("OM SAI RAM")
        self.showFullScreen() 
        #self.setCursor(Qt.BlankCursor)
        button = QPushButton("Click", self) 
        button.clicked.connect(self.change)
        button.move(10,10)    
        button.show()

    def change(self):
        self.newpage = Authentication_page()
        self.close()

    def printKey(self, key):
        if key == 'A':
            self.newpage = Authentication_page()
            self.close()

class Authentication_page(QWidget):
    """
    Class to validate authentication.
    """
    def __init__(self):
        super().__init__()
        self.showFullScreen() 
        self.maindesign()

    def maindesign(self):
        """Method to design main page"""
        ####Label###
        self.admin_header = QLabel("Admin Panel", self)
        self.admin_header.setStyleSheet("font-size:40px")
        self.admin_header.move(130, 10)
        self.admin_header.show() 

当我点击按钮代码工作正常但当我按下机械按钮时,代码冻结并显示错误消息。

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 qthread


    【解决方案1】:

    registerKeyPressHandler 分配的处理程序在监控键的线程中执行,在您的情况下,printKey 在您尝试创建小部件但被 Qt 禁止的辅助线程中执行。

    解决方案是创建一个 QObject 并通过发送按下的键来发出信号(因为信号是线程安全的),然后连接到接收信息的插槽:

    from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
    from PyQt5.QtWidgets import QLabel, QPushButton, QWidget
    
    from pad4pi import rpi_gpio
    
    
    class KeypadManager(QObject):
        keyPressed = pyqtSignal(object)
    
        def __init__(self, parent=None):
            super().__init__(parent)
            factory = rpi_gpio.KeypadFactory()
            self._keypad = factory.create_4_by_4_keypad()
            self._keypad.registerKeyPressHandler(self._key_press_handler)
    
        def _key_press_handler(self, key):
            self.keyPressed.emit(key)
    
    
    class DigitalClock(QWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.setWindowTitle("OM SAI RAM")
            self._keypad_manager = KeypadManager()
            self._keypad_manager.keyPressed.connect(self.printKey)
    
            # self.setCursor(Qt.BlankCursor)
            button = QPushButton("Click", self)
            button.clicked.connect(self.show_authentication_page)
            button.move(10, 10)
    
            self.showFullScreen()
    
        def show_authentication_page(self):
            self.newpage = Authentication_page()
            self.close()
    
        @pyqtSlot(object)
        def printKey(self, key):
            if key == "A":
                self.show_authentication_page()
    
    
    class Authentication_page(QWidget):
        # ...
    

    【讨论】:

    • 您能否指导我如何在 pyqt5 中使用 while 循环而不冻结 GUI。目前我正在使用“QtCore.QCoreApplication.processEvents()”,但它也有很多限制。
    • @ShorabhKarir 在不同的线程上运行它,如果你想从那个while循环更新GUI,那么你必须通过信号来完成。在 SO 中有很多关于你所说的问题。你做过搜索吗?我认为不是,请投入时间。
    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    相关资源
    最近更新 更多