Solved Widget class from pyside2-uic ui class not shown when adding to a tab widget
-
Hi! This is probably a dumb question. I am new to PySide2.
I created a ui class with pyside2-uic after creating a ui file in the designer manually.
Then, I created a widget class from the ui class like that:from PySide2.QtWidgets import QWidget from ui_main import Ui_main_widget class WUIMain(QWidget): def __init__(self): super(WUIMain, self).__init__() self.ui = Ui_main_widget() self.ui.setupUi(self)
And I am using it in MainWindow:
# ... class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui_main = WUIMain() self.ui.classes_tab_widget.setCurrentWidget(self.ui_main)
The widget of the current tab stays blank. Any ideas, what I could have missed?
Adding a new tab with it works. Recreating the tab would be possible but a bit bad design.EDIT
The problem does not rely on the ui_main thing, it has to do with the tab widget itself. The following code does not show a button:from PySide2.QtWidgets import QMainWindow from PySide2.QtWidgets import QPushButton from ui_main_window import Ui_MainWindow class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) print(self.ui.classes_tab_widget.currentIndex()) # prints 0 self.my_button = QPushButton('hi!') self.ui.classes_tab_widget.setCurrentWidget(self.my_button)
Thank you!
-
@Niagarer said in Widget class from pyside2-uic ui class not shown when adding to a tab widget:
self.my_button = QPushButton('hi!')
self.ui.classes_tab_widget.setCurrentWidget(self.my_button)I don't understand what you think you are doing here?! I think you are misunderstanding how a
QTabWidget
works. https://doc.qt.io/qt-5/qtabwidget.html#setCurrentWidget:Makes widget the current widget. The widget used must be a page in this tab widget.
But you are trying to set the
QTabWidget
's current widget to aQPushButton
you have just created, which is most certainly not " a page in this tab widget"! :) Your currentsetCurrentWidget(self.my_button)
is silently doing nothing.For a
QTabWidget
you want a number of plainQWidget
s to be created as "pages" via https://doc.qt.io/qt-5/qtabwidget.html#addTab. It it is one of thoseQWidget
s which you must pass tosetCurrentWidget()
to make that one be the current, visible one. You add widgets you create like aQPushButton
onto one of those page widgets (and you will probably want to add a layout onto each of the page widgets to hold its child widgets).Not that this is not the way to do it long-term, but from where you are now so that you understand you should see your button somewhere on the current page widget (you say you have created one in the designer since
self.ui.classes_tab_widget.currentIndex() == 0
) if you try, say:self.my_button = QPushButton('hi!') page = self.ui.classes_tab_widget.currentWidget() if page is None: # in your case you probably don't need this bit by the sound of it page = QWidget() self.ui.classes_tab_widget.addTab(page, "Label") self.ui.classes_tab_widget.setCurrentWidget(page) if page.layout() is None: # and you may not need this page.setLayout(QVBoxLayout()) page.layout().addWidget(self.my_button)
Not that it matters, but your issue has nothing to do with PyQt/Python, or your use of Qt Designer.
And there is absolutely nothing wrong with using plain
super()
, I and others do it all the time and it is recommended by the official https://docs.python.org/3/library/functions.html#super:In a class hierarchy with single inheritance, super can be used to refer to parent classes without naming them explicitly, thus making the code more maintainable. This use closely parallels the use of super in other programming languages.
The need to use
ParentClass.__init__(self)
instead ofsuper().__init__()
was in Python 2. Since you are using Python 3 not Python 2, and since you are only using it in a single-inheritance situation inside a method here, it is fine. -
@Denni-0
Sorry for the confusion, I didn't provide more because the problem does not rely on the ui_main thing. I will just update the question. I changed the super statements as you suggested, I can't tell where your notation shouldn't work anymore right now so I will stick to that. I didn't know that there were these problems with pythons super so far, now I know.I also tried it with a simple QPushButton which doesn't work as well. What is preventing the tab widget to show the widgets?
print(self.ui.classes_tab_widget.currentIndex())
prints 0, so the tab should be created at this point - just before I set the widget. -
@Niagarer said in Widget class from pyside2-uic ui class not shown when adding to a tab widget:
self.my_button = QPushButton('hi!')
self.ui.classes_tab_widget.setCurrentWidget(self.my_button)I don't understand what you think you are doing here?! I think you are misunderstanding how a
QTabWidget
works. https://doc.qt.io/qt-5/qtabwidget.html#setCurrentWidget:Makes widget the current widget. The widget used must be a page in this tab widget.
But you are trying to set the
QTabWidget
's current widget to aQPushButton
you have just created, which is most certainly not " a page in this tab widget"! :) Your currentsetCurrentWidget(self.my_button)
is silently doing nothing.For a
QTabWidget
you want a number of plainQWidget
s to be created as "pages" via https://doc.qt.io/qt-5/qtabwidget.html#addTab. It it is one of thoseQWidget
s which you must pass tosetCurrentWidget()
to make that one be the current, visible one. You add widgets you create like aQPushButton
onto one of those page widgets (and you will probably want to add a layout onto each of the page widgets to hold its child widgets).Not that this is not the way to do it long-term, but from where you are now so that you understand you should see your button somewhere on the current page widget (you say you have created one in the designer since
self.ui.classes_tab_widget.currentIndex() == 0
) if you try, say:self.my_button = QPushButton('hi!') page = self.ui.classes_tab_widget.currentWidget() if page is None: # in your case you probably don't need this bit by the sound of it page = QWidget() self.ui.classes_tab_widget.addTab(page, "Label") self.ui.classes_tab_widget.setCurrentWidget(page) if page.layout() is None: # and you may not need this page.setLayout(QVBoxLayout()) page.layout().addWidget(self.my_button)
Not that it matters, but your issue has nothing to do with PyQt/Python, or your use of Qt Designer.
And there is absolutely nothing wrong with using plain
super()
, I and others do it all the time and it is recommended by the official https://docs.python.org/3/library/functions.html#super:In a class hierarchy with single inheritance, super can be used to refer to parent classes without naming them explicitly, thus making the code more maintainable. This use closely parallels the use of super in other programming languages.
The need to use
ParentClass.__init__(self)
instead ofsuper().__init__()
was in Python 2. Since you are using Python 3 not Python 2, and since you are only using it in a single-inheritance situation inside a method here, it is fine. -
@JonB
Oh really? I didn't quite get the page thing, that's the missing piece. I just misinterpreted this method, thank you! And once again Qt's doc rules. As long as you read the detailed class description too where this is explained in detail :) My bad. I'm sorry.
https://doc.qt.io/qt-5/qtabwidget.html#details
I usedsuper()
so far too since it's used also in Qt's documentation.
@JonB said in Widget class from pyside2-uic ui class not shown when adding to a tab widget:The need to use
ParentClass.__init__(self)
instead ofsuper().__init__()
was in Python 2. Since you are using Python 3 not Python 2, and since you are only using it in a single-inheritance situation inside a method here, it is fine.Multi-inheritance should be fine too actually I guess, as long as you follow the
__mro__
order correctly. This post could be useful@Denni-0 said in Widget class from pyside2-uic ui class not shown when adding to a tab widget:
@Niagarer note btw unless you have to use that QtDesigner UI I would stop using it -- because (1) you most likely are not using it for what it was designed for so you are just being lazy ;-) and (2) what it produces is not proper Python-Qt code (3) Creating black-box untouchable modules in a program is never a good idea if it can be avoided (4) Creating a GUI properly in Python-Qt is actually surprisingly easy, straight forward and when you are done you have a much better understanding of what you have and can easily modify it later on.
I just convert my UI files to python scripts with PySide2-uic. Is there something wrong with that? The code looks pretty efficient to me...
-
@Niagarer said in Widget class from pyside2-uic ui class not shown when adding to a tab widget:
I just convert my UI files to python scripts with PySide2-uic. Is there something wrong with that? The code looks pretty efficient to me...
I think it and using Qt Designer is fine, with about the same advantages & disadvantages as other GUI designers. @Denni-0 strongly objects to it. It basically boils down to whether you want a GUI designer or prefer to code your UI dynamically yourself, they both have pros & cons.