How to get a if a KeySequence is pressed in main(); (While Application Launch)
-
In main - because I want to get the KeyEvent before the MainWindow appears - see top to this thread.
@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
In main
no, you don't...
-
Ok guys - you have been right - but still it does not work. I changed within main() to:
// Create a pixmap to show on the splash screen
QPixmap pixmap(500,100);
pixmap.fill(Qt::white);
MySplashScreen splash(pixmap);
splash.show();
splash.raise();
... and so on -
Ok guys - you have been right - but still it does not work. I changed within main() to:
// Create a pixmap to show on the splash screen
QPixmap pixmap(500,100);
pixmap.fill(Qt::white);
MySplashScreen splash(pixmap);
splash.show();
splash.raise();
... and so on -
Ok guys - you have been right - but still it does not work. I changed within main() to:
// Create a pixmap to show on the splash screen
QPixmap pixmap(500,100);
pixmap.fill(Qt::white);
MySplashScreen splash(pixmap);
splash.show();
splash.raise();
... and so onThis works for me:
QPixmap pixmap(500,100); pixmap.fill(Qt::white); MySplashScreen splash(pixmap); splash.show(); QTimer::singleShot(3000, &app, [&]() { // even with finish() outside the lamda, // but then you have to be fast with pressing the key splash.finish(&w); app.processEvents(); // needed?! w.show(); });@jsulm clicking will make the Splash screen disappear.
The above code works for me on Windows without doing anything... Splash shows up, I spamESC-key, I get dozens ofKey pressedmessages from myqDebugin SplashScreen'skeyEventhandler.Edit:
Weird that I don't even need the
processEventscall... commented that line, still works. -
This works for me:
QPixmap pixmap(500,100); pixmap.fill(Qt::white); MySplashScreen splash(pixmap); splash.show(); QTimer::singleShot(3000, &app, [&]() { // even with finish() outside the lamda, // but then you have to be fast with pressing the key splash.finish(&w); app.processEvents(); // needed?! w.show(); });@jsulm clicking will make the Splash screen disappear.
The above code works for me on Windows without doing anything... Splash shows up, I spamESC-key, I get dozens ofKey pressedmessages from myqDebugin SplashScreen'skeyEventhandler.Edit:
Weird that I don't even need the
processEventscall... commented that line, still works.@Pl45m4 Hi - thx again. I copied your code 1:1 and added "MainWindow w;" above.
when I am not mistaken I should get - as you do "Any key printed" as Debug message, because I have
a genial log message for any Key also.But still - being on Mac OS - I do not get a Debug() message and also, when I run in Debugger mode, the routine gets never hit.
I ll try on windows - for cross test now ...
-
@Pl45m4 Hi - thx again. I copied your code 1:1 and added "MainWindow w;" above.
when I am not mistaken I should get - as you do "Any key printed" as Debug message, because I have
a genial log message for any Key also.But still - being on Mac OS - I do not get a Debug() message and also, when I run in Debugger mode, the routine gets never hit.
I ll try on windows - for cross test now ...
-
Hi, to both of you - I can approve on Windows 11 it is working as expected.
Hence the question is whats needed for MacOS to get it work or is it a Bug ...@jsulm Yep I will test the flags and let you know.
@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
Hence the question is whats needed for MacOS to get it work or is it a Bug ...
Either bug or just how it works on Mac...
See:
(also includes a workaround... )maybe worth a try if you are fine with creating an empty widget/window before the splashscreen is created
-
@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
Hence the question is whats needed for MacOS to get it work or is it a Bug ...
Either bug or just how it works on Mac...
See:
(also includes a workaround... )maybe worth a try if you are fine with creating an empty widget/window before the splashscreen is created
@Pl45m4 Hi, thx for pointing me to the stack overflow thread. I have tried two things:
-
I just added this splash.grabKeyboard();:
In this case the key event gets hit, when MainWindow is active. -
The solution from stack overflow is adding a "hidden" window before the Splashscreen is called.
But also in this case the key event gets hit, when MainWindow is active. This would have a negative effect on the Main Application for sure.
Maybe the simplest way is to create my Own "Dialog" or Framless Widget as a Splashscreen replacement ...
The Event filter should be no longer active, when the dialog has been closed - right? -
-
@Pl45m4 Hi, thx for pointing me to the stack overflow thread. I have tried two things:
-
I just added this splash.grabKeyboard();:
In this case the key event gets hit, when MainWindow is active. -
The solution from stack overflow is adding a "hidden" window before the Splashscreen is called.
But also in this case the key event gets hit, when MainWindow is active. This would have a negative effect on the Main Application for sure.
Maybe the simplest way is to create my Own "Dialog" or Framless Widget as a Splashscreen replacement ...
The Event filter should be no longer active, when the dialog has been closed - right?@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
I just added this splash.grabKeyboard();:
In this case the key event gets hit, when MainWindow is active.This part of the solution is not relevant for you.
The solution from stack overflow is adding a "hidden" window before the Splashscreen is called.
But also in this case the key event gets hit, when MainWindow is active. This would have a negative effect on the Main Application for sure.I was talking about this part.
Can't test it, as I don't use any Mac, but how should this influence your main window?!
You do literally nothing with this label... it's just there to somehow bypass the Mac behavior.
You don't even see it, because it has no size and is hidden when you show your main app.
Otherwise I'm out of ideas.
You could try another widget instead ofQSplashScreenbut you said, you want to use a splashscreen for your app anyway.// Create a dummy window so that we get keypresses on OSX QLabel v(0, Qt::FramelessWindowHint); v.setMinimumSize(QSize(0, 0)); v.move(0,0); v.show(); // ... // your code v.hide(); -
-
@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
I just added this splash.grabKeyboard();:
In this case the key event gets hit, when MainWindow is active.This part of the solution is not relevant for you.
The solution from stack overflow is adding a "hidden" window before the Splashscreen is called.
But also in this case the key event gets hit, when MainWindow is active. This would have a negative effect on the Main Application for sure.I was talking about this part.
Can't test it, as I don't use any Mac, but how should this influence your main window?!
You do literally nothing with this label... it's just there to somehow bypass the Mac behavior.
You don't even see it, because it has no size and is hidden when you show your main app.
Otherwise I'm out of ideas.
You could try another widget instead ofQSplashScreenbut you said, you want to use a splashscreen for your app anyway.// Create a dummy window so that we get keypresses on OSX QLabel v(0, Qt::FramelessWindowHint); v.setMinimumSize(QSize(0, 0)); v.move(0,0); v.show(); // ... // your code v.hide();@Pl45m4 Yes and yes - but even if this label has been hidden the KeyEvent get still caught within the MainWindow ...
Hence if the user presses ESC, while in the MainWindow again, the same/associated action will take place again.
This is not what wanted. -
@Pl45m4 Yes and yes - but even if this label has been hidden the KeyEvent get still caught within the MainWindow ...
Hence if the user presses ESC, while in the MainWindow again, the same/associated action will take place again.
This is not what wanted.@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
even if this label has been hidden the KeyEvent get still caught within the MainWindow ...
Hence if the user presses ESC, while in the MainWindow again, the same/associated action will take place again.Have you tried it already?
Again:
I'm not able to test it, but the label does nothing, except fooling the Mac Window System to process input events (seems like it).
The label does not react on any key event or print any messages.
You just add the label to your code. Show it before you show the splash, hide it with the splash before the main window shows up.
Does it work now? -
@Pl45m4 thx for your patience.
Using a custom Widget could work, but when MainWindow is to be shown the Application crashes.
I am not very familiar with LAMBDA functions. May I did it wrong.SplashWidget *splash = new SplashWidget; splash->show(); splash->raise(); splash->setFocus(); MainWindow w; QTimer::singleShot(3000, [&]() { splash->close(); app.processEvents(); w.show(); }); -
@Pl45m4 thx for your patience.
Using a custom Widget could work, but when MainWindow is to be shown the Application crashes.
I am not very familiar with LAMBDA functions. May I did it wrong.SplashWidget *splash = new SplashWidget; splash->show(); splash->raise(); splash->setFocus(); MainWindow w; QTimer::singleShot(3000, [&]() { splash->close(); app.processEvents(); w.show(); });@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
SplashWidget *splash = new SplashWidget;You allocate the widget on the heap
QTimer::singleShot(3000, [&]() {and capture it by reference.
Keep it on the stack (dont create pointer)
It's a bad habit to allocate everything on the heap when not needed at all
(minimize heap allocations)You can also safely remove the
processEvents()call. -
@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
SplashWidget *splash = new SplashWidget;You allocate the widget on the heap
QTimer::singleShot(3000, [&]() {and capture it by reference.
Keep it on the stack (dont create pointer)
It's a bad habit to allocate everything on the heap when not needed at all
(minimize heap allocations)You can also safely remove the
processEvents()call.@Pl45m4
Do I understand right - you want me to do this:SplashWidget splash; splash.show(); splash.raise(); splash.setFocus(); MainWindow w; QTimer::singleShot(3000, [&]() { splash.close(); w.show(); });When I keep a key (any) pressed the Application crashes immediately, after the SplashWidget had been closed.
8 QtCore 0x109aa8e9d qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) + 13 (qlogging.cpp:1937)
9 QtCore 0x109bb5118 QDebug::~QDebug() + 104 (qdebug.cpp:154)
10 SplashCommand 0x107be933f SplashWidget::keyPressEvent(QKeyEvent*) + 159 (splashwidget.cpp:17)
11 SplashCommand 0x107be9403 SplashWidget::keyPressEvent(QKeyEvent*) + 355 (splashwidget.cpp:22)
.... many more -
@Pl45m4
Do I understand right - you want me to do this:SplashWidget splash; splash.show(); splash.raise(); splash.setFocus(); MainWindow w; QTimer::singleShot(3000, [&]() { splash.close(); w.show(); });When I keep a key (any) pressed the Application crashes immediately, after the SplashWidget had been closed.
8 QtCore 0x109aa8e9d qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) + 13 (qlogging.cpp:1937)
9 QtCore 0x109bb5118 QDebug::~QDebug() + 104 (qdebug.cpp:154)
10 SplashCommand 0x107be933f SplashWidget::keyPressEvent(QKeyEvent*) + 159 (splashwidget.cpp:17)
11 SplashCommand 0x107be9403 SplashWidget::keyPressEvent(QKeyEvent*) + 355 (splashwidget.cpp:22)
.... many more -
From the call trace it seem to crash in your key event handler implementation inside your splash widget class.
Does it crash if you press the key only or every time? -
It does not crash - while the Splash Screen is visible.
At the moment, where the screen vanishes the crash happens.
I would assume the "Event Handler" is not deleted properly at widget.close(); ...Check what line exactly causes the crash.
@ademmler said in How to get a if a KeySequence is pressed in main(); (While Application Launch):
I would assume the "Event Handler" is not deleted properly at widget.close();
The event handling function is a member of the widget itself... or is there any event filter involved?
Ok, from looking at your code again:
MainWindow w; QTimer::singleShot(3000, [&]() { splash.close(); // [ 1 ] w.show(); });I would say you ran into the infamous
quitOnLastWindowClosed"mistake"...
Closing the Splash at[ 1 ], which at that moment, is the last remaining window/widget, will terminate your app.
That's one of the reasonsQSplashScreenfor example has theQSplashScreen::finish(QWidget *mainWindow)method.It delays the closing of the splashscreen until the main application window is shown.
So change the order or set this setting to false... but then your app won't even exit when closing the main window and in this case you really want to quit your app.