Issue opening new window
-
Hello all,
I have done a lot of programming with C++ and Qt, and finally ventured into the Python/Qt world. I am using PySide6 currently for this application.
I am trying to have a
QPushButtonopen a new window upon click, and I have this part working with the following code:# This Python file uses the following encoding: utf-8 import sys import openpyxl as pyxl import datetime from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget # Important: # You need to run the following command to generate the ui_form.py file # pyside6-uic form.ui -o ui_form.py, or # pyside2-uic form.ui -o ui_form.py from ui_form import Ui_Widget from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreen class Widget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked) @QtCore.Slot() def add_machine_button_clicked(self): self.local = AddNewMachineScreen() self.local_widget = QWidget() self.local.setupUi(self.local_widget) self.local_widget.show() def main(): populate_licenses_available() populate_machines_in_year_label() populate_not_shipped_machines() def find_year_in_workbook(col: str): # Grabbing the current year year = datetime.date.today().year # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Setting variables for while loop found = False row = 1 # Iterating over rows and reading Column R to find the specific year while not found: if worksheet[col + str(row)].value == str(year) + " Count": found = True else: row += 5 return row def populate_licenses_available(): # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Grabbing the row which the current year is located row = find_year_in_workbook("R") # Setting the label based upon the License Avalaible value widget.ui.licenseAnsLabel.setText(str(worksheet["S" + str(row+3)].value)) def populate_not_shipped_machines(): # Local variables amt_not_shipped = 0 # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Iterating over the "E" column for row in worksheet.iter_rows(): if row[4].value == "n": amt_not_shipped += 1 # Setting the label based upon the amount of machines not shipped widget.ui.notShippedAnsLabel.setText(str(amt_not_shipped)) def populate_machines_in_year_label(): # Grabbing the current year year = datetime.date.today().year widget.ui.machinesInYearLabel.setText("MACHINES IN " + str(year)) # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Grabbing the row which the current year is located row = find_year_in_workbook("R") # Setting the label based upon the Used Licenses value widget.ui.machinesInYearAnsLabel.setText(str(worksheet["S" + str(row+2)].value)) if __name__ == "__main__": app = QApplication(sys.argv) widget = Widget() widget.show() main() sys.exit(app.exec())# This Python file uses the following encoding: utf-8 import sys from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget from ui_addNewMachineScreen import Ui_Widget class AddNewMachineScreen(QWidget, Ui_Widget): def __init__(self): super().__init__() self.setupUi(self) print("here0") self.connect_slots(self) def connect_slots(self): print("here1") self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed) @QtCore.Slot() def calibrate_check_state_changed(self, int): print("here2") if __name__ == "__main__": app = QApplication(sys.argv) add_machine = AddNewMachineScreen() add_machine.show() print("here") sys.exit(app.exec())My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console. I was curious if someone can point me in the right direction?
Am I not opening the secondary window correctly? Maybe it is an issue with what I am passing to the
__init__(self)method within the AddNewMachineScreen.py file? Maybe I need to pass the parent window as a parameter?Thank you in advance for any assistance, or pointers as to what I am doing wrong so far!
-
This is very helpful, but I am having trouble getting the screen to open now.
I have these files
# This Python file uses the following encoding: utf-8 import sys from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget from ui_addNewMachineScreen import Ui_Widget class AddNewMachineScreen(QWidget): def __init__(self): super(AddNewMachineScreen, self).__init__() self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): print("here1") self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed) @QtCore.Slot() def calibrate_check_state_changed(self, int): print("here2") if __name__ == "__main__": app = QApplication(sys.argv) print("here") add_machine = AddNewMachineScreen() add_machine.show() sys.exit(app.exec())widget.py (only showing the slot function, as it is all that matters I believe being the button click slot is what is supposed to open the page)
import AddNewMachineScreen as anms @QtCore.Slot() def add_machine_button_clicked(self): anms.AddNewMachineScreen()It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct? I am going to look a bit more into this, because there is definitely something super simple I am missing and I know I will kick myself for it. Thanks a lot for the link!
@orsini29 said in Issue opening new window:
It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct?
Well, yes.
-
anms.AddNewMachineScreen()creates a newAddNewMachineScreeninstance, which calls its constructor. That's all it does: nothing here shows the widget. -
Furthermore: you do not assign the returned instance to anything. In C++ if you just write
new AddNewMachineScreen();(which would be the equivalent) that would leave an (unreferenced) instance lying around, forever. But Python reference counts objects, and destroys them when no in-scope references remain.anms.AddNewMachineScreen()creates an instance, and then as soon as that statement completes destroys it because nothing is referencing it. You will need to assign it to something. And if you use a local variable that will go at the end of that function. If you want the widget to persist you will likely want to assign it to a class member variable inwidget.py, or pass it a parent so that it lives as long as the parent.
-
-
Hello all,
I have done a lot of programming with C++ and Qt, and finally ventured into the Python/Qt world. I am using PySide6 currently for this application.
I am trying to have a
QPushButtonopen a new window upon click, and I have this part working with the following code:# This Python file uses the following encoding: utf-8 import sys import openpyxl as pyxl import datetime from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget # Important: # You need to run the following command to generate the ui_form.py file # pyside6-uic form.ui -o ui_form.py, or # pyside2-uic form.ui -o ui_form.py from ui_form import Ui_Widget from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreen class Widget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked) @QtCore.Slot() def add_machine_button_clicked(self): self.local = AddNewMachineScreen() self.local_widget = QWidget() self.local.setupUi(self.local_widget) self.local_widget.show() def main(): populate_licenses_available() populate_machines_in_year_label() populate_not_shipped_machines() def find_year_in_workbook(col: str): # Grabbing the current year year = datetime.date.today().year # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Setting variables for while loop found = False row = 1 # Iterating over rows and reading Column R to find the specific year while not found: if worksheet[col + str(row)].value == str(year) + " Count": found = True else: row += 5 return row def populate_licenses_available(): # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Grabbing the row which the current year is located row = find_year_in_workbook("R") # Setting the label based upon the License Avalaible value widget.ui.licenseAnsLabel.setText(str(worksheet["S" + str(row+3)].value)) def populate_not_shipped_machines(): # Local variables amt_not_shipped = 0 # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Iterating over the "E" column for row in worksheet.iter_rows(): if row[4].value == "n": amt_not_shipped += 1 # Setting the label based upon the amount of machines not shipped widget.ui.notShippedAnsLabel.setText(str(amt_not_shipped)) def populate_machines_in_year_label(): # Grabbing the current year year = datetime.date.today().year widget.ui.machinesInYearLabel.setText("MACHINES IN " + str(year)) # Grabbing the excel workbook/worksheet workbook = pyxl.load_workbook("workbook.xlsx", data_only = True) worksheet = workbook["worksheet"] # Grabbing the row which the current year is located row = find_year_in_workbook("R") # Setting the label based upon the Used Licenses value widget.ui.machinesInYearAnsLabel.setText(str(worksheet["S" + str(row+2)].value)) if __name__ == "__main__": app = QApplication(sys.argv) widget = Widget() widget.show() main() sys.exit(app.exec())# This Python file uses the following encoding: utf-8 import sys from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget from ui_addNewMachineScreen import Ui_Widget class AddNewMachineScreen(QWidget, Ui_Widget): def __init__(self): super().__init__() self.setupUi(self) print("here0") self.connect_slots(self) def connect_slots(self): print("here1") self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed) @QtCore.Slot() def calibrate_check_state_changed(self, int): print("here2") if __name__ == "__main__": app = QApplication(sys.argv) add_machine = AddNewMachineScreen() add_machine.show() print("here") sys.exit(app.exec())My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console. I was curious if someone can point me in the right direction?
Am I not opening the secondary window correctly? Maybe it is an issue with what I am passing to the
__init__(self)method within the AddNewMachineScreen.py file? Maybe I need to pass the parent window as a parameter?Thank you in advance for any assistance, or pointers as to what I am doing wrong so far!
@orsini29 said in Issue opening new window:
My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console
I don't understand this. As soon as
self.local = AddNewMachineScreen()executes (do you get there) that would callAddNewMachineScreen.__init__(). At minimum I would expect that toprint("here0")andprint("here1")at least?Back in
widget.pyafter showingwidgetyou gomain(). What is that? You don't define it. I don't know what it does or why you call it. I have never seen a Python Qt program, whether PySide or PyQt, call or define it. -
@orsini29 said in Issue opening new window:
My issue is, that when the AddNewMachineScreen window opens, the slots do not connect, as I can see by the messages not being printed to the console
I don't understand this. As soon as
self.local = AddNewMachineScreen()executes (do you get there) that would callAddNewMachineScreen.__init__(). At minimum I would expect that toprint("here0")andprint("here1")at least?Back in
widget.pyafter showingwidgetyou gomain(). What is that? You don't define it. I don't know what it does or why you call it. I have never seen a Python Qt program, whether PySide or PyQt, call or define it.Sorry about excluding
main(), this was just a function to run a couple of functions in sequential order. Should this have just been done in the constructor rather than a separate function for it like I did?I updated widget.py above to include the function, once again sorry for omitting it! It is just functionality I had left out in the question from the overall program itself, being the issue arises without it. Although I forgot to omit the
main()function call like you had said, so I understand the confusion.I as well am confused, but once I press
addMachineButtonit opens ui_addNewMachineScreen, and nothing prints, nor does the checkbox slot ever connect, because nothing prints when I check theQCheckBox calibrateCheck -
Sorry about excluding
main(), this was just a function to run a couple of functions in sequential order. Should this have just been done in the constructor rather than a separate function for it like I did?I updated widget.py above to include the function, once again sorry for omitting it! It is just functionality I had left out in the question from the overall program itself, being the issue arises without it. Although I forgot to omit the
main()function call like you had said, so I understand the confusion.I as well am confused, but once I press
addMachineButtonit opens ui_addNewMachineScreen, and nothing prints, nor does the checkbox slot ever connect, because nothing prints when I check theQCheckBox calibrateCheck@orsini29 said in Issue opening new window:
I as well am confused, but once I press addMachineButton it opens ui_addNewMachineScreen, and nothing prints
Why don't you step through in debugger? I see
def add_machine_button_clicked(self):callingself.local = AddNewMachineScreen(). Inclass AddNewMachineScreen(QWidget, Ui_Widget)function__init__()I seeprint("here0")as the 3rd statement. I would expect that to print? Put it as first statement? -
@orsini29 said in Issue opening new window:
I as well am confused, but once I press addMachineButton it opens ui_addNewMachineScreen, and nothing prints
Why don't you step through in debugger? I see
def add_machine_button_clicked(self):callingself.local = AddNewMachineScreen(). Inclass AddNewMachineScreen(QWidget, Ui_Widget)function__init__()I seeprint("here0")as the 3rd statement. I would expect that to print? Put it as first statement?I changed the
__init__to be the following within AddNewMachineScreen.pydef __init__(self): print("here0") super().__init__() self.setupUi(self) self.connect_slots(selfAnd put a breakpoint on the following line within widget.py
@QtCore.Slot() def add_machine_button_clicked(self): self.local = AddNewMachineScreen() ####BREAKPOINT HERE self.local_widget = QWidget() self.local.setupUi(self.local_widget) self.local_widget.show()Then when using F11 to Step Into, when it gets to the line with the breakpoint it just goes to the next line
self.local_widget = QWidget()and it does not go into a function until theself.local.setupUi(self.local_widget)goes into theui_addnewmachinescreen.pyfile.This is saying it basically does not run the constructor for the AddNewMachineScreen class...thinking out loud trying to figure out why.
It could not have anything to do with the following import statement, right? I assumed this is correct syntax as I do not see why it would not be valid...
from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreen -
I changed the
__init__to be the following within AddNewMachineScreen.pydef __init__(self): print("here0") super().__init__() self.setupUi(self) self.connect_slots(selfAnd put a breakpoint on the following line within widget.py
@QtCore.Slot() def add_machine_button_clicked(self): self.local = AddNewMachineScreen() ####BREAKPOINT HERE self.local_widget = QWidget() self.local.setupUi(self.local_widget) self.local_widget.show()Then when using F11 to Step Into, when it gets to the line with the breakpoint it just goes to the next line
self.local_widget = QWidget()and it does not go into a function until theself.local.setupUi(self.local_widget)goes into theui_addnewmachinescreen.pyfile.This is saying it basically does not run the constructor for the AddNewMachineScreen class...thinking out loud trying to figure out why.
It could not have anything to do with the following import statement, right? I assumed this is correct syntax as I do not see why it would not be valid...
from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreen@orsini29
I had not noticed that. I am OK an Python, but not an expert. Yes, it must be the explanation for inexplicable behaviour you report.I don't know what you think are trying to achieve, but you are "messing it up" :)
class AddNewMachineScreen(QWidget, Ui_Widget)This defines a class named
AddNewMachineScreen(). And callingAddNewMachineScreen()would invoke its__init__()as I was expecting.from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreenThis "redefines"
AddNewMachineScreen. It now "refers to"Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides theclassdefinition. So invokingAddNewMachineScreen()now actually doesUi_Widget(), whatever that does. Hence you never create anAddNewMachineScreenor hit its__init__().I do not claim to understand what you are trying to do. I can say that you have absolutely no need to do an
import ... as ..., that is just for aliasing. I suggest whatever you are trying to achieve you remove any such construct and start over.... -
@orsini29
I had not noticed that. I am OK an Python, but not an expert. Yes, it must be the explanation for inexplicable behaviour you report.I don't know what you think are trying to achieve, but you are "messing it up" :)
class AddNewMachineScreen(QWidget, Ui_Widget)This defines a class named
AddNewMachineScreen(). And callingAddNewMachineScreen()would invoke its__init__()as I was expecting.from ui_addNewMachineScreen import Ui_Widget as AddNewMachineScreenThis "redefines"
AddNewMachineScreen. It now "refers to"Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides theclassdefinition. So invokingAddNewMachineScreen()now actually doesUi_Widget(), whatever that does. Hence you never create anAddNewMachineScreenor hit its__init__().I do not claim to understand what you are trying to do. I can say that you have absolutely no need to do an
import ... as ..., that is just for aliasing. I suggest whatever you are trying to achieve you remove any such construct and start over....So my understanding was this,
from ui_addNewMachineScreen I am importing Ui_Widget, and I want to reference this as AddNewMachineScreen within my code. Which is basically what you had explained here (below) if I am understanding correctly.
@JonB said in Issue opening new window:
This "redefines" AddNewMachineScreen. It now "refers to" Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides the class definition. So invoking AddNewMachineScreen() nwo actually does Ui_Widget(), whatever that does.
The reason I did this, is because if I do the following import I come across the following issue
# This Python file uses the following encoding: utf-8 import sys import openpyxl as pyxl import datetime from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget # Important: # You need to run the following command to generate the ui_form.py file # pyside6-uic form.ui -o ui_form.py, or # pyside2-uic form.ui -o ui_form.py from ui_form import Ui_Widget from ui_addNewMachineScreen import Ui_Widget #the above import was changed from original one mentioned in post aboveredefinition of unused 'Ui_Widget' from line 13Which makes sense for this error, being I am importing
Ui_Widgettwice, on line 12 and 13.How would I mitigate this issue? I am new to Python within Qt, so I was wondering if you had a general skeleton that is normally followed to get this to work. Thanks in advance!
Edit: wait a second. I am thinking to far into it. I just need to make the alias name after the "as" command, something OTHER then the class name, correct? If so, so sorry for the confusion on my part!
Edit 2: Okay so I belive my first edit was incorrect. I guess now I am confused on how to get into the
__init__method of the AddNewMachineScreen class. Sorry, I am a Python newbie I'm sure my questions are elementary...Because I had changed the import/slot to the following:
# This Python file uses the following encoding: utf-8 import sys import openpyxl as pyxl import datetime from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget # Important: # You need to run the following command to generate the ui_form.py file # pyside6-uic form.ui -o ui_form.py, or # pyside2-uic form.ui -o ui_form.py from ui_form import Ui_Widget from ui_addNewMachineScreen import Ui_Widget as temp #####HERE class Widget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked) self.ui.editMachineButton.clicked.connect(self.edit_machine_button_clicked) self.ui.removeMachineButton.clicked.connect(self.remove_machine_button_clicked) @QtCore.Slot() def add_machine_button_clicked(self): self.local = temp() #####HERE self.local_widget = QWidget() self.local.setupUi(self.local_widget) self.local_widget.show()But the
__init__still doesn't run, because the AddNewMachineScreen is never called...so would I just need to import the AddNewMachineScreen.py and then instantiate the object? -
So my understanding was this,
from ui_addNewMachineScreen I am importing Ui_Widget, and I want to reference this as AddNewMachineScreen within my code. Which is basically what you had explained here (below) if I am understanding correctly.
@JonB said in Issue opening new window:
This "redefines" AddNewMachineScreen. It now "refers to" Ui_Widget, as an "alias". It cannot also refer to the class you defined at the same time. I guess in Python this overrides the class definition. So invoking AddNewMachineScreen() nwo actually does Ui_Widget(), whatever that does.
The reason I did this, is because if I do the following import I come across the following issue
# This Python file uses the following encoding: utf-8 import sys import openpyxl as pyxl import datetime from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget # Important: # You need to run the following command to generate the ui_form.py file # pyside6-uic form.ui -o ui_form.py, or # pyside2-uic form.ui -o ui_form.py from ui_form import Ui_Widget from ui_addNewMachineScreen import Ui_Widget #the above import was changed from original one mentioned in post aboveredefinition of unused 'Ui_Widget' from line 13Which makes sense for this error, being I am importing
Ui_Widgettwice, on line 12 and 13.How would I mitigate this issue? I am new to Python within Qt, so I was wondering if you had a general skeleton that is normally followed to get this to work. Thanks in advance!
Edit: wait a second. I am thinking to far into it. I just need to make the alias name after the "as" command, something OTHER then the class name, correct? If so, so sorry for the confusion on my part!
Edit 2: Okay so I belive my first edit was incorrect. I guess now I am confused on how to get into the
__init__method of the AddNewMachineScreen class. Sorry, I am a Python newbie I'm sure my questions are elementary...Because I had changed the import/slot to the following:
# This Python file uses the following encoding: utf-8 import sys import openpyxl as pyxl import datetime from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget # Important: # You need to run the following command to generate the ui_form.py file # pyside6-uic form.ui -o ui_form.py, or # pyside2-uic form.ui -o ui_form.py from ui_form import Ui_Widget from ui_addNewMachineScreen import Ui_Widget as temp #####HERE class Widget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked) self.ui.editMachineButton.clicked.connect(self.edit_machine_button_clicked) self.ui.removeMachineButton.clicked.connect(self.remove_machine_button_clicked) @QtCore.Slot() def add_machine_button_clicked(self): self.local = temp() #####HERE self.local_widget = QWidget() self.local.setupUi(self.local_widget) self.local_widget.show()But the
__init__still doesn't run, because the AddNewMachineScreen is never called...so would I just need to import the AddNewMachineScreen.py and then instantiate the object?@orsini29 said in Issue opening new window:
I just need to make the alias name after the "as" command, something OTHER then the class name, correct?
That would be an improvement :)
I don't know what any of your
from ui_... import UI_...are about/for. I never used any such in Python (or C++) Qt programming. I don't know where you get this pattern from. I wonder whether you are trying to import/expose too much. You don't usually import UI stuff from other modules, just the non-UI-named wrapper you create for each UI form. I never encountered any of your problems (in Python), it was all straightforward.I am going to have to lave you for some Python expert to answer.
-
@orsini29 said in Issue opening new window:
I just need to make the alias name after the "as" command, something OTHER then the class name, correct?
That would be an improvement :)
I don't know what any of your
from ui_... import UI_...are about/for. I never used any such in Python (or C++) Qt programming. I don't know where you get this pattern from. I wonder whether you are trying to import/expose too much. You don't usually import UI stuff from other modules, just the non-UI-named wrapper you create for each UI form. I never encountered any of your problems (in Python), it was all straightforward.I am going to have to lave you for some Python expert to answer.
Okay, thank you very much for your assistance to this point though! Much appreciated. Hopefully I can figure this out before someone else can help, if I do I will update the thread. Otherwise all assistance is appreciated!
As for the
from ui_ .... import .... as .....I believe that this statement will grab the
ui_classNamefile generated from the *.ui file, and open it up. I assume I am missing out on the pairing of this and the class itself, if I had to guess. Hopefully someone more versed in Python would be able to be of assistance. -
Okay, thank you very much for your assistance to this point though! Much appreciated. Hopefully I can figure this out before someone else can help, if I do I will update the thread. Otherwise all assistance is appreciated!
As for the
from ui_ .... import .... as .....I believe that this statement will grab the
ui_classNamefile generated from the *.ui file, and open it up. I assume I am missing out on the pairing of this and the class itself, if I had to guess. Hopefully someone more versed in Python would be able to be of assistance.@orsini29
Let me just try one other explanation. Let's talk about C++, but I think exactly the same applies to Python/PyQt/PySide.- I have two designer files for their widgets,
fred.ui&jim.ui. - I run
uicto produceui_fred.h&ui_jim.h. - I only
#include "ui_fred.h"infred.cpp, never injim.cpp, and the same the other way round. - If
fred.cppwants to talk to/usejimstuff, I#include "jim.h"infred.cpp. I do not includeui_jim.h. That is only private stuff forjim.cppto use, and if required it writes exported wrapper functions (injim.h) around any private stuff.
This should apply equally from Python stuff, with
imports and different file/module names. I have a feeling you are not doing this, you are trying to import private stuff from one to the other? - I have two designer files for their widgets,
-
@orsini29
Let me just try one other explanation. Let's talk about C++, but I think exactly the same applies to Python/PyQt/PySide.- I have two designer files for their widgets,
fred.ui&jim.ui. - I run
uicto produceui_fred.h&ui_jim.h. - I only
#include "ui_fred.h"infred.cpp, never injim.cpp, and the same the other way round. - If
fred.cppwants to talk to/usejimstuff, I#include "jim.h"infred.cpp. I do not includeui_jim.h. That is only private stuff forjim.cppto use, and if required it writes exported wrapper functions (injim.h) around any private stuff.
This should apply equally from Python stuff, with
imports and different file/module names. I have a feeling you are not doing this, you are trying to import private stuff from one to the other?Yes...what you said does make sense and I feel like I am doing exactly what you are saying, and I believe it is incorrect...now I just have to figure out how to make that encapsulation (maybe the right term, maybe not), work correctly. :D
Very helpful explanation though, with what I was doing. Made me understand it better...now to figure out how to fix this
- I have two designer files for their widgets,
-
-
This is very helpful, but I am having trouble getting the screen to open now.
I have these files
# This Python file uses the following encoding: utf-8 import sys from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget from ui_addNewMachineScreen import Ui_Widget class AddNewMachineScreen(QWidget): def __init__(self): super(AddNewMachineScreen, self).__init__() self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): print("here1") self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed) @QtCore.Slot() def calibrate_check_state_changed(self, int): print("here2") if __name__ == "__main__": app = QApplication(sys.argv) print("here") add_machine = AddNewMachineScreen() add_machine.show() sys.exit(app.exec())widget.py (only showing the slot function, as it is all that matters I believe being the button click slot is what is supposed to open the page)
import AddNewMachineScreen as anms @QtCore.Slot() def add_machine_button_clicked(self): anms.AddNewMachineScreen()It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct? I am going to look a bit more into this, because there is definitely something super simple I am missing and I know I will kick myself for it. Thanks a lot for the link!
-
This is very helpful, but I am having trouble getting the screen to open now.
I have these files
# This Python file uses the following encoding: utf-8 import sys from PySide6 import QtCore from PySide6.QtWidgets import QApplication, QWidget from ui_addNewMachineScreen import Ui_Widget class AddNewMachineScreen(QWidget): def __init__(self): super(AddNewMachineScreen, self).__init__() self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): print("here1") self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed) @QtCore.Slot() def calibrate_check_state_changed(self, int): print("here2") if __name__ == "__main__": app = QApplication(sys.argv) print("here") add_machine = AddNewMachineScreen() add_machine.show() sys.exit(app.exec())widget.py (only showing the slot function, as it is all that matters I believe being the button click slot is what is supposed to open the page)
import AddNewMachineScreen as anms @QtCore.Slot() def add_machine_button_clicked(self): anms.AddNewMachineScreen()It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct? I am going to look a bit more into this, because there is definitely something super simple I am missing and I know I will kick myself for it. Thanks a lot for the link!
@orsini29 said in Issue opening new window:
It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct?
Well, yes.
-
anms.AddNewMachineScreen()creates a newAddNewMachineScreeninstance, which calls its constructor. That's all it does: nothing here shows the widget. -
Furthermore: you do not assign the returned instance to anything. In C++ if you just write
new AddNewMachineScreen();(which would be the equivalent) that would leave an (unreferenced) instance lying around, forever. But Python reference counts objects, and destroys them when no in-scope references remain.anms.AddNewMachineScreen()creates an instance, and then as soon as that statement completes destroys it because nothing is referencing it. You will need to assign it to something. And if you use a local variable that will go at the end of that function. If you want the widget to persist you will likely want to assign it to a class member variable inwidget.py, or pass it a parent so that it lives as long as the parent.
-
-
@orsini29 said in Issue opening new window:
It has to be an issue of only calling the constructor here, and not actually saving it and showing the UI screen itself, correct?
Well, yes.
-
anms.AddNewMachineScreen()creates a newAddNewMachineScreeninstance, which calls its constructor. That's all it does: nothing here shows the widget. -
Furthermore: you do not assign the returned instance to anything. In C++ if you just write
new AddNewMachineScreen();(which would be the equivalent) that would leave an (unreferenced) instance lying around, forever. But Python reference counts objects, and destroys them when no in-scope references remain.anms.AddNewMachineScreen()creates an instance, and then as soon as that statement completes destroys it because nothing is referencing it. You will need to assign it to something. And if you use a local variable that will go at the end of that function. If you want the widget to persist you will likely want to assign it to a class member variable inwidget.py, or pass it a parent so that it lives as long as the parent.
Yes, you were right and as was I. Cannot believe I didn't think of this immediately.
Everything is fixed, thank you for your assistance!
class Widget(QWidget): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() self.add_machine_screen = anms.AddNewMachineScreen() def connect_slots(self): self.ui.addMachineButton.clicked.connect(self.add_machine_button_clicked) @QtCore.Slot() def add_machine_button_clicked(self): self.add_machine_screen.show()class AddNewMachineScreen(QWidget): def __init__(self): super(AddNewMachineScreen, self).__init__() self.ui = Ui_Widget() self.ui.setupUi(self) self.connect_slots() def connect_slots(self): print("here1") self.ui.calibrateCheck.stateChanged.connect(self.calibrate_check_state_changed) -
-
O orsini29 has marked this topic as solved on