PyQT pass data between windows, and run script in second window.
-
-
link not working?
@Denni-0 said in PyQT pass data between windows, and run script in second window.:
Well the first idea is please provide a MRE (Minimal Reproducible Example) that demonstrates what you are doing along with the issue you are having and then we can actually help you with what your issue is because we will be able to actually see it ;)
-
link not working?
Probably people do not want to look through a link which contains 9 files. The idea is for you to produce some kind of minimal example which illustrates just the problem you are having in the shortest number of lines.
I open a new window. I would like to pass data in both directions
Let's assume your "window" is a modal dialog. Then the simplest (not always the best, but we'll keep it simple) approach would be like follows:
# In Second Window module class MyDialog(QtWidgets.QDialog): def __init__(self, parent: QtWidgets.QWidget=None): super().__init__(parent) self.leMessage = QtWidgets.QLineEdit(self) def setMessage(self, text: str): self.leMessage.setText(text) def message(self) -> str: return self.leMessage.text() # In calling/main window module class MainWindow(QtWidgets.QMainWindow): def buttonClicked(self): dialog = MyDialog(self) dialog.setMessage("Hello World! Now edit this.") if dialog.exec(): msgOut = dialog.message() dialog.deleteLater()
Adapt as required. The point is that your dialog subclass has "getter"/"setter" (
message()
/setMessage()
) methods. Use the createddialog
instance to call the setter before showing the dialog/window and call the getter after the user has interacted with the dialog and clicked OK. Note: do not set theQt.WA_DeleteOnClose
flag on a dialog/window where you will want to get stuff back out of its widgets after the user has closed it. -
unfortunately I still need you. this is what I would like to do. pass the variable XXX to the Qdialog. By changing the two Qlinedit or Qslide I would like to update the values in the main.
Main GUI
# -*- coding: utf-8 -*- from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(286, 214) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.layoutWidget = QtWidgets.QWidget(self.centralwidget) self.layoutWidget.setGeometry(QtCore.QRect(40, 40, 221, 131)) font = QtGui.QFont() font.setPointSize(12) self.layoutWidget.setFont(font) self.layoutWidget.setObjectName("layoutWidget") self.gridLayout_2 = QtWidgets.QGridLayout(self.layoutWidget) self.gridLayout_2.setContentsMargins(0, 0, 0, 0) self.gridLayout_2.setObjectName("gridLayout_2") self.gridLayout = QtWidgets.QGridLayout() self.gridLayout.setObjectName("gridLayout") self.label = QtWidgets.QLabel(self.layoutWidget) font = QtGui.QFont() font.setPointSize(12) self.label.setFont(font) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.lineEdit = QtWidgets.QLineEdit(self.layoutWidget) font = QtGui.QFont() font.setPointSize(12) self.lineEdit.setFont(font) self.lineEdit.setObjectName("lineEdit") self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1) self.label_2 = QtWidgets.QLabel(self.layoutWidget) font = QtGui.QFont() font.setPointSize(12) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) self.lineEdit_2 = QtWidgets.QLineEdit(self.layoutWidget) font = QtGui.QFont() font.setPointSize(12) self.lineEdit_2.setFont(font) self.lineEdit_2.setObjectName("lineEdit_2") self.gridLayout.addWidget(self.lineEdit_2, 1, 1, 1, 1) self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1) self.pushButton = QtWidgets.QPushButton(self.layoutWidget) font = QtGui.QFont() font.setPointSize(12) self.pushButton.setFont(font) self.pushButton.setObjectName("pushButton") self.gridLayout_2.addWidget(self.pushButton, 1, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 286, 22)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Main")) self.label.setText(_translate("MainWindow", "MAX")) self.label_2.setText(_translate("MainWindow", "MIN")) self.pushButton.setText(_translate("MainWindow", "Open Dialog"))
Main:
from PyQt5 import QtWidgets, QtCore, QtGui, uic from PyQt5.QtWidgets import * import sys from Main_GUI import Ui_MainWindow from Dialog_GUI import Ui_Dialog to_dialog = [] class GUI(QtWidgets.QMainWindow): def __init__(self): super(GUI, self).__init__() self.GUI = Ui_MainWindow() self.GUI.setupUi(self) self.GUI.pushButton.clicked.connect(self.openwind) def openwind(self): my_win = Ui_Dialog(self) my_win.setM("to_dialog") app = QtWidgets.QApplication([]) application = GUI() application.show() sys.exit(app.exec())
Dialog GUI
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'Dialog.ui' # # Created by: PyQt5 UI code generator 5.13.0 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(290, 210) self.widget = QtWidgets.QWidget(Dialog) self.widget.setGeometry(QtCore.QRect(20, 50, 239, 46)) self.widget.setObjectName("widget") self.gridLayout = QtWidgets.QGridLayout(self.widget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.label = QtWidgets.QLabel(self.widget) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.horizontalSlider = QtWidgets.QSlider(self.widget) self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider.setObjectName("horizontalSlider") self.gridLayout.addWidget(self.horizontalSlider, 0, 1, 1, 1) self.lineEdit = QtWidgets.QLineEdit(self.widget) self.lineEdit.setObjectName("lineEdit") self.gridLayout.addWidget(self.lineEdit, 0, 2, 1, 1) self.label_2 = QtWidgets.QLabel(self.widget) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) self.horizontalSlider_2 = QtWidgets.QSlider(self.widget) self.horizontalSlider_2.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider_2.setObjectName("horizontalSlider_2") self.gridLayout.addWidget(self.horizontalSlider_2, 1, 1, 1, 1) self.lineEdit_2 = QtWidgets.QLineEdit(self.widget) self.lineEdit_2.setObjectName("lineEdit_2") self.gridLayout.addWidget(self.lineEdit_2, 1, 2, 1, 1) self.retranslateUi(Dialog) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.label.setText(_translate("Dialog", "MAX")) self.label_2.setText(_translate("Dialog", "MIN"))
Dialog
from PyQt5 import QtWidgets, QtCore, QtGui, uic from PyQt5.QtWidgets import * import sys to_dialog = [] class GUID(QtWidgets.QDialog): def __init__(self, parent): super().__init__(parent) self.GUID = Ui_Dialog() self.GUID.setupUi(self) def setM(self, data): self.GUID.lineEdit.setText(data)
-
@ceciacd79 Not sure what the problem with passing parameters to a dialog is:
class GUID(QtWidgets.QDialog): def __init__(self, parent, SOME_ADDITIONA_PARAMETER):
"By changing the two Qlinedit or Qslide I would like to update the values in the main" - use signals/slots for that. The dialog emits signals with changed data. These signals are connected to slots in main window...
-
@ceciacd79 said in PyQT pass data between windows, and run script in second window.:
By changing the two Qlinedit or Qslide I would like to update the values in the main.
Possibly my suggested way (examine values on dialog upon return), possibly @jsulm way (signals/slots). Pros & cons. Answer this: when the user changes values of widgets in the dialog, do you want the changes back in
MainWindow
to happen immediately as the value changes, or do you want the user to make a number of changes and then click an OK/Cancel to indicate he wants/does not want the new values to be applied? If you only want my way (the latter), I have already shown you the code you need to get the values back.To be fair, now that you have shown your dialog it does not appear to have any OK/Cancel -exiting buttons. So you wish presumably to be in the first case (immediate change), in which case you must follow @jsulm's signals/slots approach.
For the parameters into the dialog, you have a choice between what I suggested --- "setter" methods --- or @jsulm's "pass as parameter". The latter works well when you have a limited number of parameters, as you do at present; I showed you the former as I feel it scales better if many parameters. Horses for courses.
-
ok I have understand.
the last example is not complete. and recently I've been trying to learn this language. in the second window I would like to check the two values so that the minimum is never greater than the maximum and vice versa. should I write this control in the main window or in the secondary one? now I set it in the second window, but it doesn't work. -
@ceciacd79 said in PyQT pass data between windows, and run script in second window.:
but it doesn't work
Please show this code...
-
main:
from PyQt5 import QtWidgets, QtCore, QtGui, uic from PyQt5.QtWidgets import * import sys from Main_GUI import Ui_MainWindow from Dialog_GUI import Ui_Dialog to_dialog = [] class GUI(QtWidgets.QMainWindow): def __init__(self): super(GUI, self).__init__() self.GUI = Ui_MainWindow() self.GUI.setupUi(self) self.GUI.pushButton.clicked.connect(self.openwind) def openwind(self): try: my_win = Ui_Dialog(self) # my_win.setM("150") except Exception as msg: print(msg) app = QtWidgets.QApplication([]) application = GUI() application.show() sys.exit(app.exec())
dialog:
from PyQt5 import QtWidgets, QtCore, QtGui, uic from PyQt5.QtWidgets import * import sys from Dialog_GUI import Ui_Dialog val = [100, 250] class GUID(QtWidgets.QDialog): def __init__(self): super().__init__() self.GUID = Ui_Dialog() self.GUID.setupUi(self) self.GUID.horizontalSlider.setValue(val[0]) self.GUID.horizontalSlider_2.setValue(val[1]) self.GUID.lineEdit.setPlaceholderText(str(val[0])) self.GUID.lineEdit_2.setPlaceholderText(str(val[1])) self.GUID.horizontalSlider.valueChanged[int].connect(self.min_test) self.GUID.horizontalSlider_2.valueChanged[int].connect(self.max_test) def min_test(self, value): global val val[0] = int(round((value/5), 2)*5) if val[0] >= val[1]: val[1] = val[0]+1 if val[1] >= 255: val[0] = 254 val[1] = 255 self.GUID.horizontalSlider.setValue(val[0]) self.GUID.lineEdit.setPlaceholderText(str(val[0])) self.GUID.horizontalSlider_2.setValue(val[1]) self.GUID.lineEdit_2.setPlaceholderText(str(val[1])) def max_test(self, value): global val val[1] = int(round((value/5), 2)*5) if val[1] <= val[0]: val[0] = val[1]-1 if val[0] <= 0: val[0] = 0 val[1] = 1 self.GUID.horizontalSlider.setValue(val[0]) self.GUID.lineEdit.setPlaceholderText(str(val[0])) self.GUID.horizontalSlider_2.setValue(val[1]) self.GUID.lineEdit_2.setPlaceholderText(str(val[1])) def setM(self, data): self.GUID.lineEdit.setPlaceholderText(data) if __name__ == "__main__": app = QtWidgets.QApplication([]) application = GUID() application.show() sys.exit(app.exec())
gui dialog:
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'Dialog.ui' # # Created by: PyQt5 UI code generator 5.13.0 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(290, 210) self.layoutWidget = QtWidgets.QWidget(Dialog) self.layoutWidget.setGeometry(QtCore.QRect(20, 50, 239, 48)) self.layoutWidget.setObjectName("layoutWidget") self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setObjectName("gridLayout") self.label = QtWidgets.QLabel(self.layoutWidget) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.horizontalSlider = QtWidgets.QSlider(self.layoutWidget) self.horizontalSlider.setMinimumSize(QtCore.QSize(100, 20)) self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider.setObjectName("horizontalSlider") self.gridLayout.addWidget(self.horizontalSlider, 0, 1, 1, 1) self.lineEdit = QtWidgets.QLineEdit(self.layoutWidget) self.lineEdit.setObjectName("lineEdit") self.gridLayout.addWidget(self.lineEdit, 0, 2, 1, 1) self.label_2 = QtWidgets.QLabel(self.layoutWidget) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) self.horizontalSlider_2 = QtWidgets.QSlider(self.layoutWidget) self.horizontalSlider_2.setMinimumSize(QtCore.QSize(100, 20)) self.horizontalSlider_2.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider_2.setObjectName("horizontalSlider_2") self.gridLayout.addWidget(self.horizontalSlider_2, 1, 1, 1, 1) self.lineEdit_2 = QtWidgets.QLineEdit(self.layoutWidget) self.lineEdit_2.setObjectName("lineEdit_2") self.gridLayout.addWidget(self.lineEdit_2, 1, 2, 1, 1) self.retranslateUi(Dialog) QtCore.QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): _translate = QtCore.QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.label.setText(_translate("Dialog", "MAX")) self.label_2.setText(_translate("Dialog", "MIN"))
-
Actually I removed a lot of code. I thought I only put interested parties. By doing so, however, you limited the possibility of creating a file for the GUI and one for the script to be executed. Now I am attaching an image of what I would like to get in the end from my Qdialog. As you can see I have to do a math for each Qslide and Qeiditline. And I have to import different values from the main form to the qdialog. And I wish there is a realtime data update. Writing everything in a file is very long and difficult to understand.
@Denni-0 said in PyQT pass data between windows, and run script in second window.:
Okay the above does not make a lot of sense you have the class GUI which imports Main_GUI which you do not supply and Dialog_GUI which you do supply and this program contains execution code for some reason
-
no no no fish. one thing though. you are not the first to tell me not to use global variables. So when do you use them? if I wanted to pass the same variable in multiple functions?
@Denni-0 said in PyQT pass data between windows, and run script in second window.:
Each one of those could be a Sub-Classed QFrame all put together within a QVBoxLayout personally using the GridLayout is not necessary most of the time but it works.
Glancing these over though it appears to me that you could in fact make a single Sub-Class QFrame with a variable (passed in) Title and with that one simple class make all 5 of those with a minimal amount of code
"By doing so, however, you limited the possibility of creating a file for the GUI and one for the script to be executed."
I am not sure what you mean by this because I actually did not limit anything in fact I expanded things and allowed you to see how they would really be implemented so that you could then take that as a guideline to do what you wanted to do. One can easily break anything out into its own file by making it a stand alone class and in fact that is what I do with my GUI -- I have a QMainWindow that imports a standard coded (not Designer junk) QWidget that represents the Central Panel of the QMainWindow and these are 2 separate files
Further there is a real time data update but the question then becomes where do you imagine this data is coming from -- is the program pulling it out of thin air or what is going to be your source for this real-time data?
As for the Math what exactly are you trying to calculate I did not bother trying to decipher what you were attempting do as one of them had an infinite recursion issue and at a glance that which was there made little sense. Further I am actually doubting that is where that math ought to have been but that greatly depends on what is was supposed to represent.
What I would suggest you do -- set the Designer aside -- create a single sub-classed QFrame and make the first one Canny Edge Limit you have shown above as a stand alone MUC (Minimal Usable Code) and have it do the things you want it to do. Note I say QFrame over QDialog because that is what that object would be in PyQt5
If you create that stand alone MUC using what I posted as an example to build it from I think you might be able to answer your own questions but if not and you still are having problems with it -- post what you made and I will help walk you through making it look and work the way you want it to. What I provided was a MUC so that you could get an idea of how things ought to look and how they actually work when done properly. MUCs are not meant to be the full answer as I am not into giving Fish away because I would rather teach you to Fish for yourself and what I gave you should be something you can look at and if you tried perhaps figure out how to extrapolate from that to make what it is you are wanting to make. Because frankly if I give you a fish today, I will most likely have to give you another one tomorrow and the day after that and... ad infinitum
As a side note I could probably create the above in about 10 mins if I had to venture a guess but that would just be the display as I am not sure what functionality is needed under the hood