PySide: QMetaObject.connectSlotsByName emits warni

2019-06-03 07:14发布

问题:

In Qt Designer, I created a QDialog window and used pysideuic to compile that to a base class which contains a setupUi method initialising all GUI elements and which I extend to implement the functionality, as so:

class MyDialog(QtGui.QDialog, ui_file.Ui_main_dialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        ui_file.Ui_main_dialog.__init__(self)
        self.setupUi(self)

This setupUi method has calls to QtCore.QObject.connect for the signal-slot connections I created in Qt Designer, where I also added new slots to the GUI. These slots are non-existent in the base class generated by pysideuic and I added them to the MyDialog class, e.g.

    def on_list_selection_changed(self):
        self.run_btn.setEnabled(len(self.modules_list.selectedIndexes()) > 0)

For this example, the slot is called on_list_selection_changed() (with empty parameter list) in Qt Designer.

On initialisation, MyDialog.__init__ calls Ui_main_dialog.setupUi, which eventually calls QtCore.QMetaObject.connectSlotsByName (the latter two with the MyDialog instance's self which is currently being created). This emits the following line on sys.stderr:

QMetaObject::connectSlotsByName: No matching signal for on_list_selection_changed()

Still, the signal behaves correctly and the slot is called when the connected modules_list.itemSelectionChanged() (modules_list is a QListWidget).

So here is my question: why do I receive this warning? What can I do so it doesn't appear, given that it seems to be irrelevant?


Edit: Since I didn't receive any answers in the last 5 months, I thought I give a complete example to make reproducing the problem easier.

This example differs from the question above in that it only uses a QLineEdit instance. Here is the code:

import sys
from PySide import QtCore, QtGui

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        self.lineEdit = QtGui.QLineEdit(Dialog)
        self.lineEdit.setObjectName("lineEdit")
        QtCore.QObject.connect(self.lineEdit, QtCore.SIGNAL("textChanged(QString)"), Dialog.on_lineEdit_changed)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

class MainWindow(QtGui.QMainWindow, Ui_Dialog):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        Ui_Dialog.__init__(self)
        Ui_Dialog.setupUi(self, self)
    @QtCore.Slot(unicode) # signal with no arguments
    def on_lineEdit_changed(self, text):
        print 'Changed to', text

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

Note that the code for the Ui_Dialog class is generated by the pysideuic from the Qt Designer's .ui file, but I shortened it a bit to better highlight the problem.

回答1:

I have the same issue in C++. connectSlotsByName is hard-coded to output that message if it finds a slot it can't connect automatically, even though you don't need the automatic connection because you've done it explicitly yourself. You can use qInstallMsgHandler to suppress warnings in general or write the messages somewhere better but I don't think there's any way to tell connectSlotsByName that you don't care about this case in particular.



标签: python qt pyside