PyQt5:使用 QtDesigner,如何将信号与模块中定义的插槽/可调用对象连接 [英] PyQt5: Using QtDesigner, how do you connect a signal with a slot/callable defined in a module

查看:61
本文介绍了PyQt5:使用 QtDesigner,如何将信号与模块中定义的插槽/可调用对象连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 PyQt5 的初学者,请原谅我的无知
我正在尝试将按钮与我定义的功能连接

I am a total beginner with PyQt5, please excuse my ignorance
I am trying to connect a push button with a function that I defined

import sys
from PyQt5 import QtGui, QtWidgets,uic


def PrintSomething ():
    print("Hello world")

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = uic.loadUi("Auto.ui")
    window.show()
    sys.exit(app.exec_())

为了执行上述操作,我使用 QtDesigner 向 MainWindow 添加了一个插槽 ..如图所示,然后将按钮的 Pressed 信号与主窗口的插槽连接

In order to do the above I added a slot to the MainWindow using QtDesigner ..as seen in the picture and then I connected the Pressed signal for the button with the slot of the main window

当我尝试运行该应用程序时出现此错误:

When I try to run the app I am getting this error:

AttributeError: 'QMainWindow' 对象没有属性 'PrintSomething'

AttributeError: 'QMainWindow' object has no attribute 'PrintSomething'

我在这里做错了什么?

更新:

我也用过这个代码

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from Auto import Ui_MainWindow
class MainW (QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)
if __name__ == '__main__':
    #topology=topo.LoadTopology()
    app = QApplication(sys.argv)
    myapp = MainW()
    myapp.show()
    sys.exit(app.exec_())

Auto 模块是通过 pyuic5 生成的,并添加了函数 PrintSomething().这也会导致错误

Where the Auto module was generated via pyuic5 and the function PrintSomething() was added. this also results in an error

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(667, 487)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(300, 380, 95, 29))
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 667, 23))
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuExit = QtWidgets.QMenu(self.menubar)
        self.menuExit.setObjectName("menuExit")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionOpen = QtWidgets.QAction(MainWindow)
        self.actionOpen.setObjectName("actionOpen")
        self.actionSave = QtWidgets.QAction(MainWindow)
        self.actionSave.setObjectName("actionSave")
        self.actionClose = QtWidgets.QAction(MainWindow)
        self.actionClose.setObjectName("actionClose")
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionClose)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuExit.menuAction())

        self.retranslateUi(MainWindow)
        self.pushButton.pressed.connect(MainWindow.PrintSomething())
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuExit.setTitle(_translate("MainWindow", "Exit"))
        self.actionOpen.setText(_translate("MainWindow", "Open"))
        self.actionSave.setText(_translate("MainWindow", "Save"))
        self.actionClose.setText(_translate("MainWindow", "Close"))
    def PrintSomething ():
        print("Hello world")

推荐答案

你需要像这样重构你的代码:

You need to restructure your code like this:

import sys
from PyQt5 import QtGui, QtWidgets, uic

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        uic.loadUi("Auto.ui", self)

    def PrintSomething(self):
        print("Hello world")

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

但是,我认为最好在代码中连接信号,而不是通过 Qt Designer 完成所有操作:

However, I think it's better to connect up the signals in your code rather than doing it all via Qt Designer:

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        ...
        self.pushButton.clicked.connect(self.PrintSomething)

如果您更改了 PrintSomething 插槽的名称,或者想要将按钮连接到不同的插槽,那么通过 Qt 设计器更改它会非常麻烦.在您开发应用程序时,信号连接可能会经常发生变化,因此手动编码它们可能更易于管理.

If you changed the name of the PrintSomething slot, or wanted to connect the button to a different slot, it's quite a lot a hassle to change it via Qt Designer. Signal connections are likely to change quite often while you're developing your application, so coding them manually is probably more manageable.

编辑:

添加到问题中的另一个示例可以用类似的方式修复.但是,如果您打算使用 pyuic,您应该永远不要编辑它生成的模块.相反,您应该像这样简单地将它导入到您的主脚本中:

The other example added to the question can be fixed in a similar way. But if you're going to use pyuic you should never edit the module it generates. Instead, you should simply import it into your main script like this:

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from Auto import Ui_MainWindow

class MainW (QMainWindow, Ui_MainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setupUi(self)
        self.pushButton.clicked.connect(self.PrintSomething)

    def PrintSomething(self):
        print("Hello world")

if __name__ == '__main__':

    app = QApplication(sys.argv)
    myapp = MainW()
    myapp.show()
    sys.exit(app.exec_())

这篇关于PyQt5:使用 QtDesigner,如何将信号与模块中定义的插槽/可调用对象连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆