理解 pyqt 中的 connectSlotsByName() 时遇到问题?

Jeb*_*eba 5 python qt pyqt

我无法理解 pyuic4 主要使用的 connectSlotsByName() 方法。到目前为止,该类在 PyQt 文件中是单个类,这是可以的,因为我们可以使用 self ,它将在整个过程中与单个对象关联。但是当我们尝试时要使用不同文件中的各种类,就会出现问题并需要使用 connectSlotsByName() 。这是我遇到的奇怪情况。

我创建了一个堆叠小部件..

  • 我在上面放置了我的第一个小部件。它有一个名为“下一步 >”的按钮。

  • 单击下一步时,它会隐藏当前小部件并添加另一个具有“单击我”按钮的小部件。

这里的问题是第二个“点击我”按钮的点击事件没有被捕获。这是我可以为我的原始问题给出的一个最小的例子。请帮助我。

这是文件 No.1..(它具有父级堆叠小部件及其第一页)。单击下一步时,它会添加第二页,其中 file2 中有“clickme”按钮。

from PyQt4 import QtCore, QtGui

import file2

class Ui_StackedWidget(QtGui.QStackedWidget):

    def __init__(self,parent=None):

        QtGui.QStackedWidget.__init__(self,parent)

        self.setObjectName("self")
        self.resize(484, 370)
        self.setWindowTitle(QtGui.QApplication.translate("self", "stacked widget", None, QtGui.QApplication.UnicodeUTF8))

        self.createWidget1()

    def createWidget1(self):

        self.page=QtGui.QWidget()
        self.page.setObjectName("widget1")


        self.pushButton=QtGui.QPushButton(self.page)        
        self.pushButton.setGeometry(QtCore.QRect(150, 230, 91, 31))
        self.pushButton.setText(QtGui.QApplication.translate("self", "Next >", None, QtGui.QApplication.UnicodeUTF8))


        self.addWidget(self.page)


        QtCore.QMetaObject.connectSlotsByName(self.page)

          QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL('clicked()'),self.showWidget2)


    def showWidget2(self):

        self.page.hide()

        obj=file2.widget2()
        obj.createWidget2(self)


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ui = Ui_StackedWidget()
    ui.show()
    sys.exit(app.exec_()) 
Run Code Online (Sandbox Code Playgroud)

这是文件2

from PyQt4 import QtGui,QtCore

class widget2():

    def createWidget2(self,parent):

        self.page = QtGui.QWidget()
        self.page.setObjectName("page")

        self.parent=parent

        self.groupBox = QtGui.QGroupBox(self.page)
        self.groupBox.setGeometry(QtCore.QRect(30, 20, 421, 311))
        self.groupBox.setObjectName("groupBox")
        self.groupBox.setTitle(QtGui.QApplication.translate("self", "TestGroupBox", None, QtGui.QApplication.UnicodeUTF8))

        self.pushButton = QtGui.QPushButton(self.groupBox)
        self.pushButton.setGeometry(QtCore.QRect(150, 120, 92, 28))
        self.pushButton.setObjectName("pushButton")
        self.pushButton.setText(QtGui.QApplication.translate("self", "Click Me", None, QtGui.QApplication.UnicodeUTF8))        

        self.parent.addWidget(self.page)
        self.parent.setCurrentWidget(self.page)

        QtCore.QMetaObject.connectSlotsByName(self.page)

        QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL('clicked()'),self.printMessage)


    def printMessage(self):

        print("Hai")
Run Code Online (Sandbox Code Playgroud)

尽管在两个小部件中(我的意思是页面)

QtCore.QMetaObject.connectSlotsByName(self.page)
Run Code Online (Sandbox Code Playgroud)

第二个对话框中的点击信号未得到处理。预先感谢..可能是一个初学者的问题..

Max*_*vko 5

首先,这是最小的工作示例:

from sys import argv, exit
from PyQt4 import QtCore, QtGui

class widget2(QtGui.QWidget):

    def __init__(self, args):
        self.app = MainApp(args)
        QtGui.QWidget.__init__(self)
        self.setObjectName('I')

        self._layout = QtGui.QVBoxLayout(self)
        self.setLayout(self._layout)

        self.pushButtoninWidget2 = QtGui.QPushButton(self)
        self.pushButtoninWidget2.setObjectName("pushButtoninWidget2")
        self.pushButtoninWidget2.setText('Click NOW!')
        self._layout.addWidget(self.pushButtoninWidget2)

        QtCore.QMetaObject.connectSlotsByName(self)

    @QtCore.pyqtSlot()
    def on_pushButtoninWidget2_clicked(self):
        print("Hai")

class MainApp(QtGui.QApplication):
    def __init__(self, args):
        QtGui.QApplication.__init__(self, args)

if __name__ == "__main__":
    main = widget2(argv)
    main.show()
    exit(main.app.exec_())
Run Code Online (Sandbox Code Playgroud)

当您尝试按名称连接插槽时,您必须为插槽提供正确的名称,然后某人(moc、uic 或您通过调用 connectSlotsByName)必须连接它们。此类插槽的正确名称是:“on_PyQtObjectName_PyQtSignalName”。

请注意,如果我在示例中省略了 @QtCore.pyqtSlot(),则每个适当的重载都会执行一次 slot (在本例中为两次)。

您确实需要直接调用 connectSlotsByNames,因为没有 moc,当您在 C++ 中使用 QT 时,它会为您完成此操作,并且您不使用 uic 和 .ui 文件。如果你想隐式连接插槽(我总是这样做,除了在.ui中直接连接的插槽),你最好使用更多的pytonish语法:button.clicked.connect(self._mySlot)。

看看https://riverbankcomputing.com/static/Docs/PyQt5/signals_slots.html#connecting-slots-by-name


Jas*_*oon 2

您不需要致电connectSlotsByName(),只需删除这些线路即可。

在 中file2,调用QtCore.QMetaObject.connectSlotsByName(self.page)尝试执行此操作:

QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL('clicked()'), self.on_pushButton_clicked())
Run Code Online (Sandbox Code Playgroud)

这对你不起作用,因为self.on_pushBotton_clicked()插槽没有定义。我发现在 PyQt 中创建自己的连接是最简单的...我建议删除对两个类的调用connectSlotsByName...您不需要它。

另外,你的wdiget1类应该设置它的pushButton 的名称(最好是“pushButton”以外的名称,以避免与 中的按钮混淆widget2)。