Most effective way to split a GUI screen with PySide? - python

I'm writing a PySide application with a GUI meant for a touch screen. It has a main window that covers 75% of the screen and a 25% vertical panel that has buttons that control the content displayed on the main window (several widgets/screens should appear on the main window).
I've seen several different ways for doing this "split": QFrame, QStackedLayout, QStackedWidget. Being a beginner with PySide/Qt, I couldn't figure out which one is the best way to go for my specific case. Any suggestions or example applications?

QFrame with a QVBoxLayout and specify the stretch factor: (C++ code)
MainWidget main = new MainWidget();
ButtonWidget buttons = new ButtonWidget();
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(buttons);
layout->addWidget(main);
layout->setStretch(0,25);
layout->setStretch(1,75);
form->setLayout(layout);

Related

Prevent QML window from appearing before all the QML content is available

How do I prevent my QML window from being shown until all the QML content is available?
In my example below an empty window is shown after QQmlApplicationEngine is created, but the QML content doesn't appear until app.exec_() is called. The effect is exaggerated with the time.sleep(1) in my example code. The window is white, and then a second later it shows the red background.
What do I need to do so that all QML content is shown when the window appears? Or rather, how do I prevent the window from being shown until all the QML content is ready?
I am running on Windows.
QML
import QtQuick
import QtQuick.Controls
ApplicationWindow {
color: "red"
visible: true
}
Code
import time
from PySide6 import QtQml, QtWidgets
app = QtWidgets.QApplication([])
engine = QtQml.QQmlApplicationEngine("app_window.qml")
# This sleep exaggerates the issue so that you can easily observe
# that an empty window is shown by this point without QML content.
# Without the sleep the empty window looks like a white "flash"
# before the QML content is shown. I want to get rid of this "flash",
# so I don't want the empty window to ever be visible!
time.sleep(1)
app.exec_()
Here is a slow-mo recording of what I am seeing, at 1/8 speed playback, with no time.sleep(). Note how the window is white when initially shown, and then it changes to red (well, my phone made it orange). I want the window to be red from the first instant that it is visible.
Widgets and QML are two distinct beasts in the land of Qt.
Normally, you should never mix the two in one project. Read more about the difference and concepts elsewhere.
QApplication Class is the way to instantiate a Qt Widgets application. Citing the docs:
QApplication specializes QGuiApplication with some functionality needed for QWidget-based applications. It handles widget specific initialization, finalization.
For QML applications, you go with a bare QGuiApplication and a QQmlEngine instances. It's important to realize that Qt app manages its lifecycle and event loop, while Qml engine is just like a yet another scripting engine on top of the app's event loop.
There are many moving parts in Qt ecosystem. I summarized my findings in one big XMind diagram in my Telegram blog. Check it out rendered.

How would I go about making a overlay widget

How would I go about making a overlay widget with qt?
I've considered using a QPaintEvent or a QGraphicsScene, but I want to be able to add widgets and for the widget to not occupy space in a layout, causing other widgets to shift when the popup appears.
I believe the best solution is to parent the so called overlay widget to the window or even have the overlay widget be in its own window.
The first solution might be easier to do, but the overlay widget is bound to the inside of the window.
If you go with the second solution, you will have to play with the windows flags to make it borderless.
In both cases, you may have to use the raise() function to make sure your overlay widget is on top.
Discussing "using a QPaintEvent or a QGraphicsScene" is off-topic. How you draw the widget does not impact how the widget will interact with the widget stack.
If you want an example, you can take a look at the code of QCompleter which does something similar. In particular look for QCompleter::setPopup() and QCompleterPrivate::showPopup().

Adding widgets outside main window in Qt Designer

I am new to QtDesigner - in the main window when I am adding widgets, I can't add any more widgets off-screen (i.e where scrolling down would normally allow me to access and view). There is probably a very simple answer to this but I can't find it anywhere. Is the main window a fixed size that will not allow widgets to be added outside of the dimensions of the full screen?
Thanks

In Pyqt, how do I enable dragging/moving windows by the empty widget space?

Main Qt apps, and AFAIK most KDE apps let you drag windows around not just by their titlebar, but using any empty space on the window. For some reason, a basic Pyqt app like this doesn't appear to let you do that:
from PyQt4.QtGui import *
import sys
a = QApplication(sys.argv)
w = QWidget()
w.show()
sys.exit(a.exec_())
I'm looking to enable dragging the window around by the widgets in it. I found an existing StackOverflow question and answer, but it doesn't use the window manager to actually move the window, which (1) isn't like other apps, (2) isn't as pretty as when the window manager does it.
So my question is, what am I missing? How do I just pass an unused click/drag event up to the window manager for moving the window?
It turns out that for a window to be draggable by the extra space on it, you need to inherit it from QMainWindow or QDialog, not just QWidget. There you have it.
Note this is a KDE feature, implemented in the widget styles Oxygen and Breeze.

Help in designing layout with qtdesigner for python

I am working on Qtdesigner for generating a GUI for my python app.
The problem is that I had manually made the widgets and then compiled it to py. But then I found out that the components did not resize when maximised.
So I opened the .ui file in designer and selected the group box for my widgets and chose layout in grid by right clicking on it.
Even now the widgets do not resize on maximising....
Do I have to do something else ???
Thanks a lot...
To have the widgets resized with the window, you must apply a layout to your top-level object (usually QMainWindow), and then place your new widgets where you want in the layout (and maybe other layouts for a more complicated window).
NOTE: the menu items allowing to apply a layout on the main window will be available only once you have placed your first widget in it.

Categories