No taskbar entry for QDialog using console application - qt

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
show an entry on taskbar, and
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();

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;
}

Related

QT - SplashScreen implementation

I have an embedded Qt application for Linux which has the following startup code:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// Startup actions neeeded to display AppView correctly
// Black screen is shown for several seconds
// ...
QQuickView AppView;
AppView.setSource(QUrl(QStringLiteral("main.qml")));
AppView.resize(480, 800);
AppView.show();
return app.exec();
}
I'd like to remove the black screen shown before AppView and to display QML animation
instead of it.
I see two possible options here but non of them is clear. Could you please advice
which one of them is more correct and also comment/answer the questions in each.
Option 1: To display QSplashScreen at the beginnning of main().
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QSplashScreen *splash = new QSplashScreen();
splash->show();
// Startup actions neeeded to display AppView correctly
// Black screen is shown for several seconds
// ...
}
The question here is what API to use to attach QML animation to QSplashScreen?
QSplashScreen inherits from QWidget, and so as I understand, no API like QQuickWidget::setSource() can be used.
Option 2: To display another QQuickView at the beginnning of main() with attached QML animation.
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQuickView SplashView;
SplashView.setSource(QUrl(QStringLiteral("SplashScreen.qml")));
SplashView.resize(480, 800);
SplashView.show();
app.exec();
// Startup actions neeeded to display AppView correctly
// Black screen is shown for several seconds
// ...
QQuickView AppView;
AppView.setSource(QUrl(QStringLiteral("main.qml")));
AppView.resize(480, 800);
AppView.show();
}
The question here is how to to close the SplashView and to display AppView on top of it?
Thanks
Option 1 is not good idea. You should not mix Qt Quick and Qt Widgets applications.
QApplication::exec() starts event loop of main gui thread and never returns until application is quit. Although I do not like your way of handling splash screen, in this case, you can use something like this.
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl("SplashScreen.qml"));
view.resize(640, 480);
view.show();
QTimer::singleShot(2000,&view,[&view](){
view.close();
view.setSource(QUrl("main.qml"));
view.show();
});
return app.exec();
I used timer to simulate "actions to display app correctly" . You should replace that part with your class, which does actions. When actions are done that class can emit a signal in receiving slot you can close current view which shows splash screen and show main app.

Adding QTreeView to QMainWidow - strange behavior

Using the TreeModel from this tutorial:
http://qt-project.org/doc/qt-4.8/itemviews-simpletreemodel.html
this version works (shows the tree):
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow mainWin;
QFile file("default.txt");
file.open(QIODevice::ReadOnly);
TreeModel model(file.readAll());
file.close();
QTreeView *treeView = new QTreeView(mainWin.splitter);
treeView->setModel(&model);
mainWin.show();
return app.exec();
}
class MainWindow: public QMainWindow {
QSplitter* splitter;
public:
MainWindow() : QMainWindow() {
splitter = new QSplitter(Qt::Horizontal, this);
splitter->setMinimumSize(1000,1000);
}
};
and this one doesn't work:
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow mainWin;
mainWin.show();
return app.exec();
}
class MainWindow: public QMainWindow {
QSplitter* splitter;
public:
MainWindow() : QMainWindow() {
splitter = new QSplitter(Qt::Horizontal, this);
splitter->setMinimumSize(1000,1000);
QFile file("default.txt");
file.open(QIODevice::ReadOnly);
TreeModel model(file.readAll());
file.close();
QTreeView *treeView = new QTreeView(splitter);
treeView->setModel(&model);
}
};
What happens here? Is there some API misuse / undefined behavior?
I assume that with "doesn't work" you mean that the tree view stays empty.
You create the TreeModel model on the stack. That means it will be destroyed at the end of the block. In the first case, that's not a problem, because main() won't be exited before the application quits (i.e. app.exec() returns).
In the second case it is a problem, as the model will be destroyed right away at the end of the MainWindow constructor, i.e. right away, before the window is even visible.
You must create the model either on the heap (don't forget about memory management then - pass the main window (this) as parent) or make it a member variable.

remove extra widget/window in Qt

probably a simple question: I just created a new project in Qt creator and I set it to use QWidget when I created it, now how do I get rid of the window that it automatically creates when I run it? I also created my own QWidget window which I want to be the only window.
#include "widget.h"
#include <QtGui>
Widget::Widget()
{
QWidget* window = new QWidget;
addBtn = new QPushButton("Add Module");
text = new QTextEdit();
text->setReadOnly(true);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(addBtn,5);
layout->addWidget(text);
window->setLayout(layout);
window->show();
}
Widget::~Widget()
{
}
#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
change it like this
Widget::Widget()
{
addBtn = new QPushButton("Add Module");
text = new QTextEdit();
text->setReadOnly(true);
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(addBtn,5);
layout->addWidget(text);
this->setLayout(layout);
}
and try to have some time on look and try some of Qt Example (you can find it in Qt Creator)
and there is about 100 short video to learn quickly basic stuff on Qt
Qt is fun, enjoy it.

Qt application crashes on quit event on Mac OSX

I'm just starting out with Qt on a Mac and working through:
http://doc.qt.nokia.com/4.7/gettingstartedqt.html
When I run the second example which has the following code:
#include <QtGui>
int main(int argv, char **args)
{
QApplication app(argv, args);
QTextEdit textEdit;
QPushButton quitButton("Quit");
QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout layout;
layout.addWidget(&textEdit);
layout.addWidget(&quitButton);
QWidget window;
window.setLayout(&layout);
window.show();
return app.exec();
}
The application starts up fine and works fine. The only issue occurs when I click the "Quit" button. When I do that the crash reporter is invoked and osx says the app quit unexpectedly.
Anything obvious I'm doing wrong?
Thanks
The problem is the order of the delete if you declare variables on the stack. The best it to give your object parents so that they can destroy the children.
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QWidget window;
// If window get's destroyed, it will destroy it's children...
QTextEdit textEdit(&window);
QPushButton quitButton("Quit",&window);
QObject::connect(&quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
QVBoxLayout layout;
layout.addWidget(&textEdit);
layout.addWidget(&quitButton);
window.setLayout(&layout);
window.show();
return app.exec();
}
PS: Did you actually try a debugger to see where it crashes? It will give you an idea ;) My suggestion is to take a working Qt example and play with it.
PS2: The order I created the widgets also prevents the crash...
Try:
QTextEdit * textEdit = new QTextEdit;
QPushButton * quitButton = new QPushButton("Quit");

how to create window that opened when close main window?

Iam a absolute Beginner in QT..
i am trying to create window that has only text and one push button when you press it, you will get another window that has menu for program ..
but Unfortunately, i didn't know how can i create new window and connect it with main window!
so, i need to helping you
Here is a sample of main.cpp that do exactly that (you will have to modify the new window though).
#include <QtGui>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QWidget *firstWindow = new QWidget();
QLabel *text = new QLabel("Here is some text one the first window.");
QPushButton *button = new QPushButton("Button on the first window that display the other window");
QBoxLayout *layout = new QVBoxLayout();
layout->addWidget(text);
layout->addWidget(button);
firstWindow->setLayout(layout);
QWidget *secondWindow = new QWidget();
// add some things on the second window
// on button click, close the first window and show the second one
connect(button, SIGNAL(clicked(bool)), secondWindow, SLOT(show()));
connect(button, SIGNAL(clicked(bool)), firstWindow, SLOT(close()));
// display the first window at the start of the application.
firstWindow->show();
return app.exec();
}

Resources