create a multiple Mainwindow in QT - qt

Thank you for going through this post. I have searched forums,blogs and SO, but could not get what I actually need.
I am experimenting on how to display multiple mainwindows. I am using a embedded hardware board. I have successfully ported QT lib on to it.
I have written a small program.
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow text_plane;
text_plane.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
text_plane.setStyleSheet("background-color: Black;");
text_plane.show();
a.exec();
return a.exec();
}
The above code displays one window only.
Even if I create a Mainwindow w1 after text_plane.show() like
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow text_plane,w1;
text_plane.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
text_plane.setStyleSheet("background-color: Black;");
text_plane.show();
w1.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
w1.setStyleSheet("background-color: Yellow;");
w1.show();
a.exec();
return a.exec();
}
Now only the w1 window is shown. What about the text_plane window ?? how to get that back.
Can anyone help me out here to make this understand.
Thank you

First of all, I wonder, what are you trying to achieve here:
a.exec();
return a.exec();
You need to call this method only once, you know.
Second of all, both of your windows are shown (you can see it in a taskbar), but, since you set Qt::FramelessWindowHint, one of them is drawn on top of the other. You can split them by using move (or something like it):
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow w, w1;
w.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
w.setStyleSheet("background-color: Black;");
w.show();
w1.setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
w1.setStyleSheet("background-color: Yellow;");
w1.show();
w.move(0, 0);
w1.move(100, 100);
return app.exec();
}

Related

QSplashScreen disappears too quickly

I am trying to show a QSplashScreen before launching my application. The problem I have is that the QSplashScreen disappears too quickly. I would like it to show for 2 seconds before the real application loads.
Below the small example I built to show the error:
#include <QApplication>
#include <QSplashScreen>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSplashScreen *splash = new QSplashScreen;
splash->setPixmap(QPixmap(":/dredgingSplash.png"));
splash->show();
Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
splash->showMessage(QObject::tr("Setting up the main window..."), topRight, Qt::white);
QTimer::singleShot(2500, splash, SLOT(close()));
MainWindow w;
QTimer::singleShot(2500, &w, SLOT(show()));
splash->showMessage(QObject::tr("loading modules..."), topRight, Qt::white);
splash->showMessage(QObject::tr("Establishing Connections..."), topRight, Qt::white);
w.show();
delete splash;
return a.exec();
}
EDITS using QSplashScreen::finish() from official documentation:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSplashScreen *splash = new QSplashScreen;
splash->setPixmap(QPixmap(":/dredgingSplash.png"));
splash->show();
Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
splash->showMessage(QObject::tr("Setting up the main window..."), topRight, Qt::white);
MainWindow w;
splash->showMessage(QObject::tr("loading modules..."), topRight, Qt::white);
splash->showMessage(QObject::tr("Establishing Connections..."), topRight, Qt::white);
w.show();
splash->finish(&w);
return a.exec();
}
EDITS 2 using a class:
#include <QApplication>
#include <QSplashScreen>
#include <QTimer>
class ShowImageTime {
public:
void slInit();
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSplashScreen *splash = new QSplashScreen;
splash->setPixmap(QPixmap(":/dredgingSplash.png"));
splash->show();
Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;
splash->showMessage(QObject::tr("Setting up the main window..."), topRight, Qt::white);
MainWindow w;
QTimer::singleShot(3000, splash, SLOT(close()));// close splash after 4s
QTimer::singleShot(3000, &w, SLOT(ShowImageTime::slInit(this->show)));// mainwindow reappears after 4s
splash->showMessage(QObject::tr("loading modules..."), topRight, Qt::white);
splash->showMessage(QObject::tr("Establishing Connections..."), topRight, Qt::white);
w.show();
splash->finish(&w);
return a.exec();
}
I tried to play with the QTimer as I thought that could be the potential problem due to priority of loading, but unfortunately if I change QTimer::singleShot(2500, splash, SLOT(close())); with QTimer::singleShot(12500, splash, SLOT(close())); or even higher numbers, there is literally no difference, so I am not sure why that is not an option.
Also I came across this source and I also followed official documentation but that also did not help me to figure out the problem.
Also this post suggests that the problem keeps being related to the QTimer but I don't see how since bigger or smaller intervals seems not to count.
What am I missing to keep the QSplashScreen to stay for 2 seconds instead of disappearing (or not even see it) right away?
Thanks for pointing to the right direction.
The problem is, that your code is starting the timer and then continues running. So the MainWindow is created, shown and the SplashScreen is deleted/finished. The timer's timout function will trigger after all this happened. That is why it closes so quickly.
SplashScreens are usually shown, if the application start is very slow, because there is so much going on in the background. In your case, there is basically no load and the code executes super quick.
You could either use a sleep call for 2sec right after calling splash->show() or put all the code for closing the SplashScreen, showing the Mainwindow in a timer's timout slot and delete the SplashScreen there.

SIGABRT in simple message box Qt program

Got an error running the following problem:
#include <QMessageBox>
#include <QApplication>
int main() {
QApplication app();
QMessageBox msgBox(QMessageBox::Critical,
QObject::tr("text1"),
QObject::tr("text2"),
QMessageBox::Ok);
msgBox.exec();
return 0;
}
The error is:
The program breaks at QMessageBox msgBox(...);
The call stack is:
EDIT: Even after i have added QApplication instance in XTerm window named qtcreator_process_stub i see the following:
QWidget: Must construct QApplication before a QWidget
The line
QApplication app();
doesn't create a QApplication object - it actually declares a function taking no arguments and returning a QApplication! This is sometimes known as the "most vexing parse".
To actually construct the application object, you need to provide the program's arguments:
QApplication app(argc, argv);
The full program is then
#include <QMessageBox>
#include <QApplication>
int main(int argc, char **argv) {
QApplication app(argc, argv);
QMessageBox msgBox(QMessageBox::Critical,
QObject::tr("text1"),
QObject::tr("text2"),
QMessageBox::Ok);
msgBox.exec();
return 0;
}

Qt Login Dialog Box before Main Window

How do I have the user first login before getting to the main window in my QT app? I'm new to QT and have looked through the documentation and have not found anything very helpful. Thank you.
I would make this in the following way. Let's assume, that my login dialog is a QDialog:
class Login : public QDialog
{
[..]
};
In my application, I create an instance of my Login dialog and if it is accepted, i.e. closed with OK button, I open my main window:
int main(int argc, char *argv[])
{
[..]
QMainWindow mw;
Login login;
if (login.exec() == QDialog::Accepted) {
mw.show();
}
[..]
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
LoginWindow l; // create login-widget
connect(&l, SIGNAL(loggedIn), &w, SLOT(show()); // connect to mainwindow show()
l.show(); // show login-window instead of
// mainwindow at start
return a.exec();
}
You might want to :
1 - exec the loop only if the dialog is accepted, otherwise you application continues to run
2 - create the mainwindow only if accepted, cause it might be a heavy interface, which takes time to initialize
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog_Login dialog;
if(dialog.exec() == QDialog::Accepted){
MainWindow w;
w.setUser(dialog.GetUser());
w.show();
return a.exec();
}
else return 0;
}
You need to create the QApplication instance in parrallel with the login dialog.

Qt QGraphicsView not showing the scene

I am new to Qt. I got a problem. I do not want to use Qt forms to create QGprahics view I just want to code it and I can't get it work.
here is my code:
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
scene = new QGraphicsScene(this);
scene->setSceneRect(600,480,600,480);
QGraphicsEllipseItem * ellipse;
QPen pen(Qt::red);
QBrush brush(Qt::blue);
ellipse = scene->addEllipse(150,150,100,100,pen, brush);
view = new QGraphicsView(scene,this);
setCentralWidget(view);
}
MainWindow::~MainWindow()
{
delete view;
delete scene;
}
view and scene are privete members of class MainWindow.
Program just shows white screen but there is no ellipse there.
any suggestions what am I doing wrong? Thanks in advance!
I think that you problem is scene->setSceneRect(600,480,600,480);.
Your ellipse is created outside of the view.

How to create a correct exit button in qt

I'm trying to create an exit button that correctly closes the GUI I have made in QT. I have tried doing this in the following way:
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
int window_width = QApplication::desktop()->width();
int window_height = QApplication::desktop()->height();
MainWindow w;
QPushButton * quit_btn = new QPushButton;
quit_btn->setParent(w.centralWidget());
quit_btn->setGeometry(window_width-50,12,32,32);
QObject::connect(quit_btn,SIGNAL(clicked()),qApp,SLOT(quit()));
w.resize(window_width,window_height);
w.show();
return a.exec();
}
Unfortunately when I push the button, the debugger gives an error:
Invalid address specified to RtlFreeHeap( 003E0000, 0028F950 )
Can anybody point me in the right direction?
Connect the button's clicked() signal to your main window's close() slot. That way things are cleaned up properly.

Resources