New PySide6 project does not show widgets
-
When you start new UI project in QtCreator 9.0.0, with PySide6.4.1, running the script won't load the widgets.
You have to manually call centralWidget().show() to get something on the screen.Video recorded: https://www.youtube.com/watch?v=7_58210bylQ
Steps:
- New project created and run is called to verify default status
- Button is added and main layout is vertically oriented - > calling run does NOT show the button on the screen - but program taskbar is visible
- python code must be updated to show central widget - > button (and the rest of UI) is now visible, but there is NO program taskbar visible
- If both, widget.show() and widget.centralWidget().show() are both enabled, 2 windows appear.
Taskbar is visible only if I call widget.show() that turns main window on. But it does not display its content -> why?
How do we make full UI visible AND taskbar visible from PySide6 dynamic UI module example, with single window?
-
One issue I can see is that you are creating a new QMainWindow that you want to embedded in your own QMainWindow subclass. While it's not an issue per se, it's not really something you would do.
From my perspective, your
form.ui
is the main widget of your application, so you should instantiate and use it directly rather than use your MainWindow in between. The load method of QUiLoader does not act in the same fashion as when you generate the code from the.ui
file. It creates a new instance of the widget defined in that file nad if you give it a parent, then set it as parent of the newly created widget. You can see how it is used in the QUiLoader documentation details.The UI files tutorial also shows the difference between the two approaches.
-
Hi,
Can you provide a minimal script that shows this behaviour ?
-
Sure, here below is UI file and mainwindow.py.
You have to play with mainwindow python file. Enable
widget.centralWidget().show()
and/orwidget.show()
and observe how:- Taskbar is shown or not
- One or 2 windows are visible
- Button is displayed on the window or not
Target is to have 1 window, button displayed, taskbar icon visible. Code is below, or on Google Drive.
# This Python file uses the following encoding: utf-8 import os from pathlib import Path import sys from PySide6.QtWidgets import QApplication, QMainWindow from PySide6.QtCore import QFile from PySide6.QtUiTools import QUiLoader class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.load_ui() def load_ui(self): loader = QUiLoader() path = Path(__file__).resolve().parent / "form.ui" ui_file = QFile(path) ui_file.open(QFile.ReadOnly) loader.load(ui_file, self) ui_file.close() if __name__ == "__main__": app = QApplication(sys.argv) widget = MainWindow() # Default generated code # does not show widgets #widget.centralWidget().show() widget.show() sys.exit(app.exec())
form.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>606</width> <height>364</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QPushButton" name="pushButton"> <property name="text"> <string>PushButton</string> </property> </widget> </item> </layout> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>606</width> <height>24</height> </rect> </property> <widget class="QMenu" name="menuFile"> <property name="title"> <string>File</string> </property> <addaction name="actionOpen"/> </widget> <widget class="QMenu" name="menuHelp"> <property name="title"> <string>Help</string> </property> <addaction name="actionAbout"/> </widget> <addaction name="menuFile"/> <addaction name="menuHelp"/> </widget> <widget class="QStatusBar" name="statusbar"/> <action name="actionOpen"> <property name="text"> <string>Open</string> </property> </action> <action name="actionAbout"> <property name="text"> <string>About</string> </property> </action> </widget> <resources/> <connections/> </ui>
-
One issue I can see is that you are creating a new QMainWindow that you want to embedded in your own QMainWindow subclass. While it's not an issue per se, it's not really something you would do.
From my perspective, your
form.ui
is the main widget of your application, so you should instantiate and use it directly rather than use your MainWindow in between. The load method of QUiLoader does not act in the same fashion as when you generate the code from the.ui
file. It creates a new instance of the widget defined in that file nad if you give it a parent, then set it as parent of the newly created widget. You can see how it is used in the QUiLoader documentation details.The UI files tutorial also shows the difference between the two approaches.
-
Changing the code to the one below, I finally have a window, with all widgets (top menu, status bar, ...) and windows taskbar icon!
# Extend from QObject class MainWindow(QObject): def __init__(self): super(MainWindow, self).__init__() self.load_ui() self.window.show() def load_ui(self): loader = QUiLoader() path = Path(__file__).resolve().parent / "form.ui" ui_file = QFile(path) ui_file.open(QFile.ReadOnly) # Load window manually self.window = loader.load(ui_file) ui_file.close() # Now show the window self.window.show() if __name__ == "__main__": app = QApplication(sys.argv) widget = MainWindow() sys.exit(app.exec())
Thanks for the support.
-
In your case, MainWindow is just overkill. Just move the load_ui code in your main function.
-
But since the code is directly coming from QtCreator new project, shall we report this as a bug?