Qtabwidget question
-
Hello all,
I have an idea using Qtabwidget that I am unable to make work on my own, but I am still learning and I am curious to know If it's possible. I am using pyside6 with python version 3.12 in conjunction with QtDesigner
What I would like to do is create a main window that contains a tab widget. When the program is started, only one tab will exist which contains buttons for different options. When a button is clicked, I would like a new tab to open that relates to the button that was clicked.
What I would like to do is design individual widgets that would get loaded as a tab using QUILoader depending on the button that is pressed in tab1.
Right now I can kind of make it work, but I am unable to control any buttons that exist on the tabs that are opened by clicking the button on tab1.I do not expect anyone to give me step by step instructions, but if someone could tell me either yes this is possible, or no it is not, I would greatly appreciate it.
Thank you!
-
Hello all,
I have an idea using Qtabwidget that I am unable to make work on my own, but I am still learning and I am curious to know If it's possible. I am using pyside6 with python version 3.12 in conjunction with QtDesigner
What I would like to do is create a main window that contains a tab widget. When the program is started, only one tab will exist which contains buttons for different options. When a button is clicked, I would like a new tab to open that relates to the button that was clicked.
What I would like to do is design individual widgets that would get loaded as a tab using QUILoader depending on the button that is pressed in tab1.
Right now I can kind of make it work, but I am unable to control any buttons that exist on the tabs that are opened by clicking the button on tab1.I do not expect anyone to give me step by step instructions, but if someone could tell me either yes this is possible, or no it is not, I would greatly appreciate it.
Thank you!
@Kymro
Yes it is possible, it's just adding a dynamic widget (a new new page for a new tab).but I am unable to control any buttons that exist on the tabs that are opened by clicking the button on tab1
Don't what this means exactly or what you are trying to do. The buttons (or any other widgets) on the new tab page belong to that page, and should be accessible from there, just like normal.
-
@Kymro
Yes it is possible, it's just adding a dynamic widget (a new new page for a new tab).but I am unable to control any buttons that exist on the tabs that are opened by clicking the button on tab1
Don't what this means exactly or what you are trying to do. The buttons (or any other widgets) on the new tab page belong to that page, and should be accessible from there, just like normal.
@JonB thank you. What I meant was that I cannot access them with the way I am trying to load the widget. I'm not at my computer right now but basically I can't access them with classname.buttonname.clicked.connect. I am assuming it has something to do with the way I am trying to use QUILoader to load the widget as opposed to creating the widget class itself in python.
When I try to dynamically load the widget I've created in QtDesigner, do I need to make it a child of the main window, or possibly a child of the tab widget, and then use super.()init() to access the parent class?
For example:
Class newtab(mymainwindow):
Def init(self):
Super().init():I don't know if you can tell or not but at this point I basically "know just enough to be dangerous".
Later this evening I will add some actual code snippets to try and add some more context to what I'm trying to ask.
-
@JonB thank you. What I meant was that I cannot access them with the way I am trying to load the widget. I'm not at my computer right now but basically I can't access them with classname.buttonname.clicked.connect. I am assuming it has something to do with the way I am trying to use QUILoader to load the widget as opposed to creating the widget class itself in python.
When I try to dynamically load the widget I've created in QtDesigner, do I need to make it a child of the main window, or possibly a child of the tab widget, and then use super.()init() to access the parent class?
For example:
Class newtab(mymainwindow):
Def init(self):
Super().init():I don't know if you can tell or not but at this point I basically "know just enough to be dangerous".
Later this evening I will add some actual code snippets to try and add some more context to what I'm trying to ask.
@Kymro
I don't know what you are doing that is any different from callingloadUi()anywhere, e.g. for your main window. I don't think there is anything special for doing so from, say, clicking a button or adding a tab.I assume you are not mixing
loadUI()with gettinguicto generate a Python class. So you must have otherloadUi()s.The
def __init__()of any derived class should/must always callsuper().__init__()as its first statement.I don't know why a tab would be derived from a class named
mymainwindow. And if that is the class of your main window, and that contains the tab widget, it makes even less sense. -
Hello all,
I have an idea using Qtabwidget that I am unable to make work on my own, but I am still learning and I am curious to know If it's possible. I am using pyside6 with python version 3.12 in conjunction with QtDesigner
What I would like to do is create a main window that contains a tab widget. When the program is started, only one tab will exist which contains buttons for different options. When a button is clicked, I would like a new tab to open that relates to the button that was clicked.
What I would like to do is design individual widgets that would get loaded as a tab using QUILoader depending on the button that is pressed in tab1.
Right now I can kind of make it work, but I am unable to control any buttons that exist on the tabs that are opened by clicking the button on tab1.I do not expect anyone to give me step by step instructions, but if someone could tell me either yes this is possible, or no it is not, I would greatly appreciate it.
Thank you!
@Kymro said in Qtabwidget question:
Right now I can kind of make it work, but I am unable to control any buttons that exist on the tabs that are opened by clicking the button on tab1.
Have a look at the calculator example:
https://doc.qt.io/qt-6/qtdesigner-calculatorbuilder-example.html
It uses findChild to retreave controls:auto *inputSpinBox1 = formWidget->findChild<QSpinBox*>(u"inputSpinBox1"_s); auto *inputSpinBox2 = formWidget->findChild<QSpinBox*>(u"inputSpinBox2"_s); auto *outputWidget = formWidget->findChild<QLabel*>(u"outputWidget"_s); -
@Kymro said in Qtabwidget question:
Right now I can kind of make it work, but I am unable to control any buttons that exist on the tabs that are opened by clicking the button on tab1.
Have a look at the calculator example:
https://doc.qt.io/qt-6/qtdesigner-calculatorbuilder-example.html
It uses findChild to retreave controls:auto *inputSpinBox1 = formWidget->findChild<QSpinBox*>(u"inputSpinBox1"_s); auto *inputSpinBox2 = formWidget->findChild<QSpinBox*>(u"inputSpinBox2"_s); auto *outputWidget = formWidget->findChild<QLabel*>(u"outputWidget"_s);@mpergand said in Qtabwidget question:
It uses findChild to retreave controls:
That is always what you have to with
loadUi(), and always has been, is it not? So that is no different from wherever else the OP is already using it. I just don't see any difference between loading it dynamically or using a tab/page/tab widget any anywhere else.Unless the OP means "Up until now I have run
uicto generate.pyclass files; I know how to do that, but now want to play withloadUi(), with which I am not familiar". But they would have said that if that were the case.... -
@mpergand said in Qtabwidget question:
It uses findChild to retreave controls:
That is always what you have to with
loadUi(), and always has been, is it not? So that is no different from wherever else the OP is already using it. I just don't see any difference between loading it dynamically or using a tab/page/tab widget any anywhere else.Unless the OP means "Up until now I have run
uicto generate.pyclass files; I know how to do that, but now want to play withloadUi(), with which I am not familiar". But they would have said that if that were the case....@JonB I'm starting to fill in alot of gaps and things are making more sense reading your replies. Is loadUi() a pyside6 class, or a pyqt class? It was my understanding to load xml files using pyside6 you must create an instance of QUiLoader and then call the .load method to load a .ui file.
I think I'm getting closer to the root cause of my issue here
-
@JonB I'm starting to fill in alot of gaps and things are making more sense reading your replies. Is loadUi() a pyside6 class, or a pyqt class? It was my understanding to load xml files using pyside6 you must create an instance of QUiLoader and then call the .load method to load a .ui file.
I think I'm getting closer to the root cause of my issue here
@Kymro
There are various things here, and PySide does it slightly different from PyQt.load()orloadUi()are methods/functions in some class,QUiLoaderis a class. You can actually tell that because Python/C++/Qt all follow the standard convention that class names start with an uppercase letter and method/variable names start with a lowercase letter, and if everybody who posted here stuck to that both they and any code readers would be better off!If you have not done so already you must read Using .ui files from Designer or QtCreator with QUiLoader and pyside6-uic. That illustrates the two approaches to handling a
.uifile: Option A runs auiccommand at development time to produce a.pyfile which you include into your project, and has variables for all the widgets on the form; Option B does aload()/loadUi()at runtime on the.uifile, and (AFAIK) if you want to access widgets you have to "go find them" via thefindChild()shown by @mpergand earlier.Of the two I personally strongly prefer Option A: you get a reusable class, dedicated variables and at editing time in your IDE you should get code completion for all the UI stuff as a Python class has been generated for it. You could use either for your "create new tabs for tab widget dynamically at runtime".
-
@Kymro
There are various things here, and PySide does it slightly different from PyQt.load()orloadUi()are methods/functions in some class,QUiLoaderis a class. You can actually tell that because Python/C++/Qt all follow the standard convention that class names start with an uppercase letter and method/variable names start with a lowercase letter, and if everybody who posted here stuck to that both they and any code readers would be better off!If you have not done so already you must read Using .ui files from Designer or QtCreator with QUiLoader and pyside6-uic. That illustrates the two approaches to handling a
.uifile: Option A runs auiccommand at development time to produce a.pyfile which you include into your project, and has variables for all the widgets on the form; Option B does aload()/loadUi()at runtime on the.uifile, and (AFAIK) if you want to access widgets you have to "go find them" via thefindChild()shown by @mpergand earlier.Of the two I personally strongly prefer Option A: you get a reusable class, dedicated variables and at editing time in your IDE you should get code completion for all the UI stuff as a Python class has been generated for it. You could use either for your "create new tabs for tab widget dynamically at runtime".
@JonB thanks for the input, I will try to work on my project a little bit this weekend and play around with these concepts. Although option A definitely seems easier, I originally had been trying to familiarize myself with option B solely so I could use the LGPL, in case if in the future I decided to get entrepreneurial with my projects.
-
@JonB thanks for the input, I will try to work on my project a little bit this weekend and play around with these concepts. Although option A definitely seems easier, I originally had been trying to familiarize myself with option B solely so I could use the LGPL, in case if in the future I decided to get entrepreneurial with my projects.
@Kymro said in Qtabwidget question:
with option B solely so I could use the LGPL
Pardon? What does either Option A or B have to do with LGPL? I have never heard suggested that Option A is not LGPL, and indeed I would have thought that most/many Python Qt applications would go that way (though maybe I'm optimistic!). FWIW nearly all C++ applications use Option A, and they are certainly LGPL.
-
@Kymro said in Qtabwidget question:
with option B solely so I could use the LGPL
Pardon? What does either Option A or B have to do with LGPL? I have never heard suggested that Option A is not LGPL, and indeed I would have thought that most/many Python Qt applications would go that way (though maybe I'm optimistic!). FWIW nearly all C++ applications use Option A, and they are certainly LGPL.
@JonB I'm probably mistaken, but I was under the impression to fall under GPL you needed to you include your source code in the form of a .py file for the UI, and with LGPL all you had to include was the XML style .ui file, which is why I was trying to use the QUiLoader method
-
@JonB I'm probably mistaken, but I was under the impression to fall under GPL you needed to you include your source code in the form of a .py file for the UI, and with LGPL all you had to include was the XML style .ui file, which is why I was trying to use the QUiLoader method
@Kymro
Are you trying to release your code under GPL or LGPL?I have not heard of this distinction for supplying the
.uifile versus the generated.pyfile. But given that the.pyis generated from the.uiwhat do you care, you can supply both of them equally easily? Having said that, someone else may wish to comment on this.If, for whatever reason, supplying the
.uiand usingQUiLoaderis the way you want to go, fair enough. But it's a considerably worse development-time experience. There must be hundreds of Qt applications out there released under LGPL (or GPL) which choose the class-code-generation approach overQUiLoader.