在Qt Designer中,我创建了一个QDialog
窗口并使用pysideuic
将其编译为基类,该基类包含初始化所有GUI元素的setupUi
方法,并且我将其扩展为实现功能,如:
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)
对于此示例,在Qt Designer中将插槽称为on_list_selection_changed()
(带有空参数列表)。
在初始化时,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
为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
类的代码是由Qt Designer的.ui文件中的pysideuic
生成的,但我稍微缩短了一点以更好地突出显示问题。
答案 0 :(得分:4)
我在C ++中遇到同样的问题。 connectSlotsByName是硬编码的,如果找到一个无法自动连接的插槽,即使您不需要自动连接,因为您已经自己明确地完成了该操作。您可以使用qInstallMsgHandler来抑制警告,或者更好地将消息写在某处,但我不认为有任何方法可以告诉connectSlotsByName您特别关心此案例。
答案 1 :(得分: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_())