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