QWidget top level widget
-
Hi guys, how can I create a top level widgets?
int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w1; // is it top level widget? QWidget w2; // is it top level widget? w1.show(); QString ptrStr1 = QString("0x%1").arg((quintptr)w1.windowHandle(), QT_POINTER_SIZE * 2, 16, QChar('0')); QMessageBox::information(&w1, "Info1", ptrStr1, QMessageBox::StandardButton::Ok); // ok, correct window handle w2.show(); QString ptrStr2 = QString("0x%1").arg((quintptr)w2.windowHandle(), QT_POINTER_SIZE * 2, 16, QChar('0')); QMessageBox::information(&w2, "Info2", ptrStr2, QMessageBox::StandardButton::Ok); // but 0x00000000 return a.exec(); }
Whats wrong?
Thanks a lot. -
Hi
If you don't assign a parent to a QWidget it becomes top level. (a window)
You can also use setWiundowsFlags for the same effect
https://doc.qt.io/qt-6/qtwidgets-widgets-windowflags-example.htmlIm surprised that w2 is zero. Does that happen every time?
what if you swap w1 and w2 processing ?
w2.show(); QString ptrStr2 = QString("0x%1").arg((quintptr)w2.windowHandle(), QT_POINTER_SIZE * 2, 16, QChar('0')); QMessageBox::information(&w2, "Info1", ptrStr2, QMessageBox::StandardButton::Ok); w1.show(); QString ptrStr1 = QString("0x%1").arg((quintptr)w1.windowHandle(), QT_POINTER_SIZE * 2, 16, QChar('0')); QMessageBox::information(&w1, "Info", ptrStr1, QMessageBox::StandardButton::Ok);
-
@Alexey-Serebryakov
ehh so swapping them, then both works? (o.O)Well, I wonder if it's due to we do it before a.exec(); (before ever shown)
if you add a button and do it in its clicked slot, we still have one fail or what happens ?
-
@Alexey-Serebryakov said in QWidget top level widget:
// ok, correct window handle
How would you even know whether it's "correct"? :) Maybe all you mean is it's non-zero?
Since the code variants with the order swapped are functionally equivalent (the compiled code may well actually beidentical), I would guess no native window handle is actually assigned until the widgets are physically shown during the
a.exec()
, as @mrjj suggests. -
@mrjj is it correct code?
class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr) : QWidget(parent, Qt::Window) {} ~Widget(); }; int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w1; Widget w2; w1.show(); w1.windowHandle()->setScreen(QApplication::screens()[0]); w2.show(); w2.windowHandle()->setScreen(QApplication::screens()[1]); return a.exec(); }
-
Hi
Yes its correct
as such but windowHandle() can return null so could crash.Also note with setScreen that on some systems with not work as one expect as
the monitors are group by the OS as one big screen. -
Yes they should and hopefully not null even the widget was not shown yet.
So you play around with a multi screen setup ?
-
@mrjj yep.
So, I have Qt-widget based application. Also I have notification widget which must be pop up on the selected screen/monitor in right bottom corner. Like Windows notification center or how in MS Outlook.
User can select the screen which display that popup widget.
Idially I need something like this:MyPopupWidget::show(QScreen *screen) { show(); windowHandle()->setScreen(screen); }
-
@Alexey-Serebryakov
Ohh.
Like Win 10 Toast messages?But you must run on other platforms and prefer your own ?
https://doc.qt.io/qt-5/qtwidgets-desktop-systray-example.html
also for full blown usage
https://github.com/mohabouje/WinToast -
Ok, it must be totally custom.
QSystray also had issues on ubuntu over the years.So is the message also clickable like Toats are or is it more like a tooltip type ?
-
@mrjj Yes there popup widget has title, text, image, close button, links and so on. User can click them and follow to the main window by context dependency. Also popup widget can contain other user-defined custom widget.
-
Oh so its a FancyToast widget ;)
Well it should not be that hard to place it. and the rich part sounds lovely.
Do notice on some virtual Desktops, its like one big screen and you will have to move your window
to right x pos as there will be only 1 screen. -
Instantiating a
QWidget
and callingshow()
create a series of events that get processed asynchronously. It cannot be safely assumed thatwindowHandle()
returns a valid pointer right after construction and/or callingshow()
. You might be more lucky on Win10, than on UBuntu/X11.If you want to wait for the widget to be fully constructed, you have to wait for
windowHandle() != nullptr
, e.g. bywhile (!w1.windowHandle()) a.processEvents();
QWindow::isExposed()
tells if the window has been rendered on a screen. -
@Axel-Spoerl thank you,
consider example code above,
how can I show w1 widget on first monitor and w2 on second?
Now both widgets showing on the same primary monitor. -
how can I show w1 widget on first monitor and w2 on second?
Suggest you take a look at the documentation and examine
QWidget::setScreen(QScreen *screen)
.