Search code examples
qtdialogfocustaskbar

No taskbar entry for QDialog using console application


I am writing a Qt Console Application using Qt Creator 4.6.0 in Linux. I would like to show a QDialog but I do not want it to

  1. show an entry on taskbar, and
  2. steal focus from other windows.

How can I do this?

I found kind of similar question, but the solutions does not work for me as it seems that I can't use this in a console application.

Here is what I have so far which shows the dialog but it neither hides it from taskbar, nor prevents it from stealing the focus:

    QDialog splash;
    QVBoxLayout *laySplash = new QVBoxLayout(&splash);
    splash.setAttribute(Qt::WA_ShowWithoutActivating);
    splash.setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    QLabel *lblText = new QLabel;
    laySplash->addWidget(lblText);
    lblText->setText(QString::fromStdString("test"));
    QTimer::singleShot(1000, &splash, SLOT(close()));
    splash.exec();

Solution

  • The set parameters with exec() seems contradicting and won't prevent showing a blocking modal dialog that steals focus, if you just show() the dialog instead of exec(), other settings work. below code was tested on Debian Ubuntu 17.10, and achieves desired results

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        //
        QDialog splash;
        QVBoxLayout *laySplash = new QVBoxLayout(&splash);
        splash.setAttribute(Qt::WA_ShowWithoutActivating);
        splash.setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
        QLabel *lblText = new QLabel;
        laySplash->addWidget(lblText);
        lblText->setText(QString::fromStdString("test"));
        QTimer::singleShot(5000, &splash, SLOT(close()));
        splash.show();
        //
        return a.exec();
    }
    

    Update:

    If the code should work before or without a main event loop (before a.exec() is called or even without at all calling a.exec()), you need to enter an event loop to host your dialog, this can be repeated for each additional code separately; eventually you might opt to return any int value depending on your code.

    #include <QEventLoop>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        //
        QDialog splash;
        QVBoxLayout *laySplash = new QVBoxLayout(&splash);
        splash.setAttribute(Qt::WA_ShowWithoutActivating);
        splash.setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
        QLabel *lblText = new QLabel;
        laySplash->addWidget(lblText);
        lblText->setText(QString::fromStdString("test"));
        QEventLoop ev;
        splash.show();
        QTimer::singleShot(5000, &ev, &QEventLoop::quit);
        ev.exec();
        //
        // More code .. more event loops
        //
        return 0;
    }