如何从QWidget返回值

时间:2018-09-30 20:11:54

标签: python pyqt pyqt5

我有一个小部件,以按OK按钮结束。我希望该小部件向主程序返回一个值(在简单示例中,该值在获得的值下方增加1)。我该怎么办?

还有,还有其他更优雅的方式来显示具有不同标题的相同QWidget吗?

MWE:

import sys
from PyQt5 import QtGui, QtCore, QtWidgets

class MainWindow(QtWidgets.QWidget):
    def __init__(self,val):
        self.val=val
        super(MainWindow, self).__init__()
        self.initUI()

    def initUI(self):
        self.End= QtWidgets.QPushButton('OK', self)
        self.End.clicked.connect(self.end)

        MainLayout = QtWidgets.QVBoxLayout()
        MainLayout.addWidget(self.End)
        self.setLayout(MainLayout)
        self.setWindowTitle(str(self.val))
        self.show()

    def end(self):
        # return self.val+1
        self.close()

def main(): 
    app = QtWidgets.QApplication(sys.argv)

    for i in range(10):
        ex = MainWindow(i)
        ex.show()
        res = app.exec_()
        print(res)
    sys.exit()

if __name__ == '__main__':
    main()

2 个答案:

答案 0 :(得分:1)

如果您想使用小部件在某些处理后获得一些价值,则正确的做法是使用QDialog,如果您使用exec_(),则可以防止打开任何其他窗口:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Dialog(QtWidgets.QDialog):
    def __init__(self, val, parent=None):
        super(Dialog, self).__init__(parent)
        self.val = val
        self.initUI()

    def initUI(self):
        endButton = QtWidgets.QPushButton('OK')
        endButton.clicked.connect(self.on_clicked)
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(endButton)
        self.setWindowTitle(str(self.val))

    @QtCore.pyqtSlot()
    def on_clicked(self):
        self.val += 1
        self.accept()

def main(): 
    app = QtWidgets.QApplication(sys.argv)
    for i in range(10):
        ex = Dialog(i)
        ex.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        if ex.exec_() == QtWidgets.QDialog.Accepted:
            print(ex.val)

if __name__ == '__main__':
    main()

答案 1 :(得分:0)

目前尚不清楚此代码的意图是什么。如果应该将val用作MainWindow实例数量的计数器,则必须将其声明为静态实例:

class MainWindow(QtWidgets.QWidget):
    val = 0
    def __init__(self):
        super(MainWindow, self).__init__()
        MainWindow.val += 1
        self.initUI()

    def initUI(self):
        # ...
        self.setWindowTitle(str(MainWindow.val))
        # ...

def main():
    # ...
    for i in range(10):
        ex = MainWindow()
        # ...
    # ...

致电QWidget::setWindowTitle()没什么错,所以我在这里看不到问题。

如果您真的想将其作为非静态类成员,并且每个MainWindow都将其用作某种ID,则可以在ex.show()之后轻松调用该值:

def main(): 
    app = QtWidgets.QApplication(sys.argv)

    for i in range(10):
        ex = MainWindow()
        ex.show()
        print(MainWindow.val)
        res = app.exec_()
        print(res)
    sys.exit()

仅仅因为您关闭了一个小部件并不意味着您已经销毁了它,所以调用存储在对象内部的值并不是问题。

但是,您似乎对QApplication::exec()的用途并不熟悉。它运行给定应用程序的主循环并返回退出状态(您可以在调用exit()作为传递给该函数的参数时进行设置)。如果您只想在关闭窗口小部件时获取val的值,则可以简单地覆盖closeEvent处理程序并发出信号。创建一个QObject实例,并将每个MainWindow实例的自定义关闭信号连接到插槽,并使用您想要的值进行操作。