简体   繁体   中英

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

I am trying to use signals and slots to update an element in my program. The first page opens and reads the config file to set some labels. I have an "Options" page that you can update the config file. What I want to happen is when you click "save" on the second window it saves to the config, and then on the first page runs a function (read_Config) that will then read the updated config file and update the label to change. I have tried multiple different methods and am failing to understand how the signals and slots work. Thanks for your help. Here is the code, it is two files. test.py and config.ini.

This is the 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()

And this is the config.ini file:

[default]
labelone = This is a label

Thanks to anyone who takes the time to help me with this. UnclassedPenguin

You have the following errors:

  • The Pagetwo constructor does not use the parent parameter so parent() will be None:

     class Pagetwo(QtWidgets.QMainWindow): trigger = pyqtSignal() def __init__(self, parent): # <----- super(Pagetwo, self).__init__() # <---- You have to pass # ...
  • It is recommended that the connection be made only once because the connection does not discriminate if there was already the connection, for example if you press n times the save button of Pagetwo then there will be n connections so it will call the same slot n times, in this case what It is better to do it in the constructor.

  • When it is connected, the name of the function is used, that is, you should not invoke it with the () .

Considering the above, the solution is:

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()

    # ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM