如何从非 PyQt 类发出信号?

the*_*232 5 python twisted pyqt pyqt4 python-2.7

我正在使用 Twisted 和 PyQt 在 python 中编写应用程序。我面临的问题是,当我扭曲代码中的一个函数被执行时,我必须在 GUI 中打印一行,我试图通过发出信号(非 PyQt 类)来实现这一点。这似乎不起作用,我怀疑扭曲的事件循环正在为 PyQt 搞砸事情。因为 closeEvent 信号没有被程序捕获。

这是代码片段:

from PyQt4 import QtGui, QtCore
import sys
from twisted.internet.protocol import Factory, Protocol
from twisted.protocols import amp
import qt4reactor

class register_procedure(amp.Command):
    arguments = [('MAC',amp.String()),
                        ('IP',amp.String()),
                        ('Computer_Name',amp.String()),
                        ('OS',amp.String())
                        ]
    response = [('req_status', amp.String()),
         ('ALIGN_FUNCTION', amp.String()),
                         ('ALIGN_Confirmation', amp.Integer()),
                         ('Callback_offset',amp.Integer())
                        ]

class Ui_MainWindow(QtGui.QMainWindow):

    def __init__(self,reactor, parent=None):
        super(Ui_MainWindow,self).__init__(parent)
        self.reactor=reactor
        self.pf = Factory()
        self.pf.protocol = Protocol
        self.reactor.listenTCP(3610, self.pf) # listen on port 1234

        def setupUi(self,MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(903, 677)
        self.centralwidget = QtGui.QWidget(MainWindow)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)

        self.create_item()


        self.retranslateUi(MainWindow)
        self.connect(self, QtCore.SIGNAL('triggered()'), self.closeEvent)
        QtCore.QObject.connect(self,QtCore.SIGNAL('registered()'),self.registered)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton_4.setText(_translate("MainWindow", "Delete System ", None))
        self.pushButton.setText(_translate("MainWindow", "Add System", None))
        self.label_2.setText(_translate("MainWindow", "SYSTEM STATUS", None))
        self.label.setText(_translate("MainWindow", "Monitoring Output", None))


    def registered(self):# this function is not being triggered
        print "check" 
        self.textbrowser.append()

    def closeEvent(self, event):#neither is this being triggered
        print "asdf"
        self.rector.stop()
        MainWindow.close()
        event.accept()


class Protocol(amp.AMP):
    @register_procedure.responder
    def register_procedure(self,MAC,IP,Computer_Name,OS):
        self.bridge_conn=bridge()
        cursor_device.execute("""select * FROM devices where MAC = ?;""",[(MAC)])
        exists_val=cursor_device.fetchone()
        cursor_device.fetchone()
        print "register"
        if not exists_val== "":
            cursor_device.execute("""update devices set IP= ? , Computer_name= ? , OS = ?  where MAC= ?;""",[IP,Computer_Name,OS,MAC])
            QtCore.QObject.emit( QtCore.SIGNAL('registered')) # <--emits signal
            return {'req_status': "done" ,'ALIGN_FUNCTION':'none','ALIGN_Confirmation':0,'Callback_offset':call_offset(1)}
        else:
            cursor_device.execute("""INSERT INTO devices(Mac,Ip,Computer_name,Os) values (?,?,?,?);""",[MAC,IP,Computer_Name,OS])
            QtCore.QObject.emit( QtCore.SIGNAL('registered'))#<--emits signal
            return {'req_status': "done" ,'ALIGN_FUNCTION':'main_loop()','ALIGN_Confirmation':0,'Callback_offset':0}



if  __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)

    try:
        import qt4reactor
    except ImportError:
        from twisted.internet import qt4reactor
    qt4reactor.install()

    from twisted.internet import reactor
    MainWindow = QtGui.QMainWindow() # <-- Instantiate QMainWindow object.
    ui = Ui_MainWindow(reactor)
    ui.setupUi(MainWindow)
    MainWindow.show()
    reactor.run()
Run Code Online (Sandbox Code Playgroud)

Rad*_*io- 0

两个基本问题是:

1)某些东西必须知道信号的发送者和接收者

考虑 Qt 中更常见的情况,您可能有多个按钮,每个按钮都有一个“单击”信号。插槽需要知道单击了哪个按钮,因此捕获通用信号没有多大意义。

2) 信号必须源自 QObject。


话虽如此,我不确定规范的实现是什么。这是一种方法,使用您在之前的一篇文章中提到的 Bridge 的想法,以及 Protocol 中的特殊 Emitter 类。当调用 protocol.register() 时,运行此代码将简单地打印“Working it”。

from PyQt4 import QtGui, QtCore
import sys

class Ui_MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()

    def work(self):
        print "Working it"

class Protocol(object):
    class Emitter(QtCore.QObject):
        registered = QtCore.pyqtSignal()
        def __init__(self):
            super(Protocol.Emitter, self).__init__()

    def __init__(self):
        self.emitter = Protocol.Emitter()

    def register(self):
        self.emitter.registered.emit()

class Bridge(QtCore.QObject):
    def __init__(self, gui, protocol):
        super(Bridge, self).__init__()
        self.gui = gui
        self.protocol = protocol

    def bridge(self):
        self.protocol.emitter.registered.connect(self.gui.work)

app = QtGui.QApplication(sys.argv)
gui = Ui_MainWindow()
protocol = Protocol()
bridge = Bridge(gui, protocol)
bridge.bridge()
#protocol.register() #uncomment to see 'Working it' printed to the console
Run Code Online (Sandbox Code Playgroud)