简体   繁体   中英

pyqt - signal error between classes

i need a string from the main window to be displayed on a dialog and im having some issues...

heres my code:

class Ui_MainWindow(QtGui.QMainWindow):
    drive_signal = QtCore.pyqtSignal(str)

    def setupUi(self, MainWindow):
       MainWindow.setObjectName(_fromUtf8("MainWindow"))
       MainWindow.resize(459, 280)
       ..... #non relevant code
       .....

       drives = win32api.GetLogicalDriveStrings()
       drives = drives.split('\000')[:-1][1:]
       self.drive_combo.clear()
       self.drive_combo.addItems(drives)
       self.drive_signal.emit(self.drive_combo.currentText())
       ..... 
       .....

class SubDialog(QtGui.QDialog):
    def setupUi(self, Dialog):
       Dialog.setWindowTitle(Ui_MainWindow.drive_signal.connect())
       Dialog.resize(532, 285)
       ..... 
       .....

but i get this error:

AttributeError: 'PyQt4.QtCore.pyqtSignal' object has no attribute 'connect'

any help?

There are two errors on this line:

Dialog.setWindowTitle(Ui_MainWindow.drive_signal.connect())

Firstly, the two method calls are round the wrong way, and secondly, you are attempting to connect an unbound signal to a slot, which can't work.

For the code to work, it would need to look something like this:

window.drive_signal.connect(dialog.setWindowTitle)

where window is an instance of Ui_MainWindow , and dialog is an instance of SubDialog .

Given the way the rest of the code is written, there may also be potential issues with the way the classes are initialized.

The code below shows one way to get the signal working correctly. Take careful note of the order in which things are done before starting the event loop:

from PyQt4 import QtGui, QtCore

class Ui_MainWindow(QtGui.QMainWindow):
    drive_signal = QtCore.pyqtSignal(str)

    def setupUi(self, MainWindow):
        MainWindow.resize(459, 280)
        MainWindow.setWindowTitle('MainWindow: Foo')
        self.drive_signal.emit('Dialog: Bar')

class SubDialog(QtGui.QDialog):
    def setupUi(self, Dialog):
        Dialog.resize(532, 285)

if __name__ == '__main__':

    import sys

    app = QtGui.QApplication(sys.argv)

    window = Ui_MainWindow()
    dialog = SubDialog()

    window.drive_signal.connect(dialog.setWindowTitle)

    window.setupUi(window)
    dialog.setupUi(dialog)

    window.show()
    dialog.show()

    sys.exit(app.exec_())

I would make it so that the Ui_MainWindow emits the signal:

self.emit(SIGNAL("something_happened"), self.drive_combo.currentText())

And then connect it the old fashioned way in the other object:

mainWindow.something_happened.connect(self.change_windowTitle)

def change_window_title(self, text):
    dialog.setWindowTitle(text)

This may help: http://www.saltycrane.com/blog/2008/01/pyqt-how-to-pass-arguments-while/

Ah, the famous 'has no attribute connect' … In fact, in SubDialog , UI_MainWindow.drive_signal is a pyqtSignal , the generic class. You need to use an instance in order to be able to connect it to a function, and this instanciation has to be done at runtime (as far as I understand it). The way PyQt and PySide know how to do that is to look in the class attributes of your PyQt objects. In other terms, you have to define the signal not only where you want to emit it, but also where you want to catch it.

class SubDialog(QtGui.QDialog):
    drive_signal = QtCore.pyqtSignal(str)

    def setupUi(self, Dialog):
        self.dialog_ui = Dialog
        self.drive_signal.connect(self.on_drive_signal))
        …

    def on_drive_signal(self, str_):
        self.dialog_ui.setWindowTitle(str_)

That should work. Please note that you need to connect your signal with something, as illustrated above…

You might also be interested in this question .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM