尝试使用 PyQt5 在两个 类 之间发送信号以更改来自 configparser 的标签

Trying to send signal between two classes with PyQt5 to change label from configparser

我正在尝试使用信号和槽来更新程序中的元素。 第一页打开并读取配置文件以设置一些标签。 我有一个 "Options" 页面,您可以在其中更新配置文件。 我想要发生的是,当您在第二个 window 上单击 "save" 时,它会保存到配置中,然后在第一页上运行一个函数 (read_Config),然后该函数将读取更新的配置文件并更新标签以更改。我尝试了多种不同的方法,但未能理解信号和槽的工作原理。谢谢你的帮助。这是代码,它是两个文件。 test.py 和 config.ini.

这是test.py:

#!/bin/usr/env python

import sys
import configparser
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication

class TestApp(QtWidgets.QMainWindow):

    def __init__(self, parent=None):
        super(TestApp, self).__init__()
        self.setupUi(self)
        self.dialogs = []
        self.read_Config()

        self.window2Button.clicked.connect(self.goto_Pagetwo)
        self.closeButton.clicked.connect(self.close)

    def read_Config(self):
        config = configparser.ConfigParser()
        config.read('config.ini')
        labelone = config['default']['labelone']
        self.label.setText(labelone)

    def goto_Pagetwo(self):
        dialog = Pagetwo(self)
        self.dialogs.append(dialog)
        dialog.show()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(244, 113)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.window2Button = QtWidgets.QPushButton(self.centralwidget)
        self.window2Button.setObjectName("window2Button")
        self.verticalLayout.addWidget(self.window2Button)
        self.closeButton = QtWidgets.QPushButton(self.centralwidget)
        self.closeButton.setObjectName("closeButton")
        self.verticalLayout.addWidget(self.closeButton)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "This is a Label"))
        self.window2Button.setText(_translate("MainWindow", "Window 2"))
        self.closeButton.setText(_translate("MainWindow", "Close"))


class Pagetwo(QtWidgets.QMainWindow):

    trigger = pyqtSignal()

    def __init__(self, parent):
        super(Pagetwo, self).__init__()
        self.setupUi(self)
        self.dialogs = []

        self.saveButton.clicked.connect(self.save)
        self.closeButton.clicked.connect(self.close)

    def save(self):
        string = self.lineEdit.text()
        config = configparser.ConfigParser()
        config.read('config.ini')
        config.set('default', 'labelone', string)
        with open('config.ini', 'w') as configfile:
            config.write(configfile)
        self.trigger.connect(self.parent().read_Config())
        self.trigger.emit()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(246, 128)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout.addWidget(self.lineEdit)
        self.saveButton = QtWidgets.QPushButton(self.centralwidget)
        self.saveButton.setObjectName("saveButton")
        self.verticalLayout.addWidget(self.saveButton)
        self.closeButton = QtWidgets.QPushButton(self.centralwidget)
        self.closeButton.setObjectName("closeButton")
        self.verticalLayout.addWidget(self.closeButton)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.saveButton.setText(_translate("MainWindow", "Save"))
        self.closeButton.setText(_translate("MainWindow", "Close"))

def main():
    app = QApplication(sys.argv)
    main = TestApp()
    main.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

这是 config.ini 文件:

[default]
labelone = This is a label

感谢所有花时间帮助我解决这个问题的人。 未分类企鹅

您有以下错误:

  • Pagetwo 构造函数不使用父参数,因此 parent() 将是 None:

    class Pagetwo(QtWidgets.QMainWindow):
        trigger = pyqtSignal()
    
        def __init__(self, parent): # <-----
            super(Pagetwo, self).__init__() # <---- You have to pass
    
        # ...
    
  • 建议只连接一次,因为连接不区分是否已经连接过,比如按了n次Pagetwo的保存键,就会有n次连接,因此它将调用同一个插槽 n 次,在这种情况下最好在构造函数中执行此操作。

  • 当连接时,使用函数名,即你不应该用().

  • 调用它

综合以上,解决方案是:

class Pagetwo(QtWidgets.QMainWindow):
    trigger = pyqtSignal()

    def __init__(self, parent=None):
        super(Pagetwo, self).__init__(parent) # <---
        self.setupUi(self)
        self.dialogs = []

        self.saveButton.clicked.connect(self.save)
        self.closeButton.clicked.connect(self.close)
        self.trigger.connect(self.parent().read_Config)  # <---

    def save(self):
        string = self.lineEdit.text()
        config = configparser.ConfigParser()
        config.read('config.ini')
        config.set('default', 'labelone', string)
        with open('config.ini', 'w') as configfile:
            config.write(configfile)
        self.trigger.emit()

    # ...