2

在 Qt Designer 中,我创建了一个QDialog窗口并将pysideuic其编译为一个基类,该基类包含一个setupUi初始化所有 GUI 元素的方法,并且我扩展它以实现功能,如下所示:

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)

这个setupUi方法调用了QtCore.QObject.connect我在 Qt Designer 中创建的信号槽连接,我还在其中向 GUI 添加了新槽。这些插槽在生成的基类中不存在,pysideuic我将它们添加到MyDialog类中,例如

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

对于此示例,on_list_selection_changed()在 Qt Designer 中调用插槽(使用空参数列表)。

在初始化时,MyDialog.__init__调用Ui_main_dialog.setupUi最终调用QtCore.QMetaObject.connectSlotsByName(后两个与当前正在创建的MyDialog实例)。self这会在 上发出以下行sys.stderr

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

尽管如此,信号表现正确,并且在连接时调用插槽modules_list.itemSelectionChanged()modules_list是 a QListWidget)。

所以这是我的问题:为什么我会收到这个警告?鉴于它似乎无关紧要,我该怎么做才能让它不出现?


编辑:由于我在过去 5 个月内没有收到任何答案,我想我举了一个完整的例子来更容易地重现问题。

这个例子与上面的问题不同,它只使用了一个QLineEdit实例。这是代码:

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

请注意,Ui_Dialog该类的代码是由pysideuicQt Designer 的 .ui 文件生成的,但我将其缩短了一点以更好地突出问题。

4

2 回答 2

4

我在 C++ 中有同样的问题。connectSlotsByName 是硬编码的,如果它找到一个无法自动连接的插槽,则输出该消息,即使您不需要自动连接,因为您自己明确地完成了它。您可以使用 qInstallMsgHandler 来抑制一般的警告或将消息写在更好的地方,但我认为没有任何方法可以告诉 connectSlotsByName 您特别不关心这种情况。

于 2014-03-17T17:30:38.327 回答
0

我迟到了,但万一其他人来这里问同样的问题。

PySide 自动连接信号,这对我来说就是这样,因为我不想手动连接。

这里我使用 python 3.9 和 PySide2,但对于 PySide6 和其他版本的 python 也是一样的。

import sys
import typing

from PySide2.QtCore import QObject, SignalInstance, Signal, Slot
from PySide2.QtWidgets import QMainWindow, QApplication

from .ui_mainwindow import Ui_MainWindow  # Don't forget to add your import


class MyQObject(QObject):
    mySignal: SignalInstance = Signal()
    otherSignal: SignalInstance = Signal(str)

    def __init__(self, parent: typing.Optional[QObject] = None) -> None:
        super().__init__(parent)


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        # Instantiate before self.setupUI
        self.myQObject = MyQObject(self)
        self.myQObject.setObjectName("syncProduct")  # do not forget this

        # Load UI from designer & init
        self.setupUi(self)

    @Slot()
    def on_myQObject_mySignal(self):
        print("Handle mySignal")

    @Slot(str)
    def on_myQObject_otherSignal(self, text: str):
        print(f"Handle otherSignal {text}")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
于 2021-04-04T22:43:41.447 回答