Remove application from memory - qt

I am trying to close an application
#include <QtGui/QApplication>
#include "battle.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
battle w;
int x = 14;
if(x == 1)
{
w.show();
}
else if(x!=1)
{
qApp->exit(0);
//Remove application from memory...
}
return a.exec();
}
but if i go to windows processes,it is still there.What is the best way to remove the application from memory?.

Don't call a.exec() after you call qApp->exit(0).

What's inside battle.h? If you start a thread in the battle class, and closing the window does not stop it, then the process will remain in the task list even if you close the window.

Related

Why isn't Qt gradually changing the opacity of a window in a loop?

I'm trying to change the opacity of the window of my program in Qt and using C++11. In other words, I want to open the main Windows slowly by adding some instructions to main.cpp. You see those instructons below:
MainWindow a;
a.show();
for(int Counter = 0; Counter <= 100; Counter++)
{
a.SetWindowOpacity(Counter);
for(Wait = 0; Wait < 100; Wait++);
}
But when I build and run my project, I don't see any changes and it normally runs. This is whole source code, main.cpp.
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("Add a new student");
w.show();
for(int Counter = 0; Counter <= 100; Counter++)
{
w.setWindowOpacity(Counter);
for(int Wait = 0; Wait < 100; Wait++);
}
return a.exec();
}
So, why don't Qt change the opacity of the window of my program?
The other answer indicates the cause of the error:
wrong range of values.
instant execution that will not make the effect visible, etc.
They also propose to use QTimer but I think a more elegant solution is to use QPropertyAnimation:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("Add a new student");
w.show();
QPropertyAnimation *animation = new QPropertyAnimation;
animation->setPropertyName("windowOpacity");
animation->setTargetObject(&w);
animation->setStartValue(0.0);
animation->setEndValue(1.0);
animation->setDuration(1000);
animation->start(QAbstractAnimation::DeleteWhenStopped);
return a.exec();
}
There are number of issues with your code. First, setWindowOpacity can take values from 0.0 to 1.0, also it does not take int but qreal, so your loop has to change and look like this:
for(qreal Counter = 0.0; qreal <= 1.0; Counter+=0.1)
{
w.setWindowOpacity(Counter);
}
Second, the loop is very fast, so even if it did change the opacity you wouldn't notice it, so if you want to see it visually changing opacity, then you need to add a sleep in between, so your loop will look like this:
for(qreal Counter = 0.0; Counter <= 1.0; Counter+=0.1)
{
w.setWindowOpacity(Counter);
QThread::msleep(100);
}
This will mean that it will change the opacity, wait 100 milliseconds and then change it again.
Third, even if you do all of this, you still won't see anything, since the opacity will change and only after that the event loop will run. And the event loop will run after the a.exec() call.
So you have to put your snippet of code somewhere else and after the window is shown. This means you have to call your opacity changing code with delayed execution. The fastest way to do it is with QTimer, so your code will look like this:
#include <QApplication>
#include <QThread>
#include <QTimer>
#include "mainwindow.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.setWindowOpacity(0.0);
w.show();
QTimer::singleShot(0, [&] {
for (qreal i = 0.0; i <= 1.0; i += 0.01) {
w.setWindowOpacity(i);
//The processEvents() call will make sure your app doesn't freeze in the process
QApplication::processEvents(QEventLoop::AllEvents, 100);
QThread::msleep(100);
}
});
return a.exec();
}

How to restart a qt application after crashing?

Is it possible to restart a qt application after its crashing? Just like those windows service which will restart on its own. If so, how could I do it? I have tried code like this:
#define RESTART_CODE 1000
int main(int argc, char *argv[])
{
int return_from_event_loop_code;
QPointer<QApplication> app;
QPointer<MainWindow> main_window;
do
{
if(app) delete app;
if(main_window) delete main_window;
app = new QApplication(argc, argv);
main_window = new MainWindow(app);
return_from_event_loop_code = app->exec();
}
while(return_from_event_loop_code==RESTART_CODE)
return return_from_event_loop_code;
}
But it is not working...
What should I do now?
create another qt application that runs your application.
#include <QApplication>
#include "QProcess"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QProcess aProcess;
QString exe = "Your process name with exact path";
QByteArray myOut;
while(1)
{
aProcess.start(exe);
//aProcess.waitForStarted();
//myOut = aProcess.readAllStandardOutput();
//printf("%s",myOut.constData());
aProcess.waitForFinished(-1);
//QString output(aProcess.readAllStandardOutput());
myOut = aProcess.readAllStandardOutput();
printf("%s",myOut.constData());
}
return a.exec();
}
this program will restart your app when it crashed or closed
You can use my open source library:
https://marketplace.qt.io/products/main-loop-wdt-for-qt-qml
It is a watchdog timer for the main loop and only works if the main loop freezes (double mutex lock, infinite loop, etc.), but it would not work in an application crash.

QDialog exec() can not exit process

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog dlg;
dlg.exec();
return a.exec();
}
That's all my code, but when I close the window, The process isn't exit, it seems that drop in the loop a.exec().
Generally speaking, calling any exec is a bad idea, other than QCoreApplication::exec() or QDrag::exec(). The presence of exec() and waitForXxx() methods is an enticing trap for the unwary. Those methods are "easy" to use, but that ease comes at a price of hard to track bugs. Don't use them.
You should simply show the dialog:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMessageBox msg;
msg.setText("Hello");
msg.addButton(QMessageBox::Close);
msg.show();
return a.exec();
}
If you wish to wait for the dialog to be accepted or rejected, you should use the dialog's clickedButton slot. QMessageBox has a long-standing bug that makes the accepted and rejected signals useless :(
// https://github.com/KubaO/stackoverflown/tree/master/questions/messagebox-show-25545652
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif
#include <functional>
[...]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMessageBox msg;
msg.setText("Continue?");
msg.addButton(QMessageBox::Yes);
msg.addButton(QMessageBox::No);
auto onClick = [&msg]() {
auto role = msg.buttonRole(msg.clickedButton());
if (role == QMessageBox::NoRole)
QApplication::quit();
if (role == QMessageBox::YesRole) {
auto label = new QLabel("I'm running");
label->setAttribute(Qt::WA_DeleteOnClose);
label->show();
}
};
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
QObject::connect(&msg, &QMessageBox::buttonClicked, onClick);
#else
QObject::connect(&msg, SIGNAL(buttonClicked(QAbstractButton*)),
new FunctorSlot{onClick, &msg}, SLOT(call()));
#endif
msg.show();
return app.exec();
}
#include "main.moc"
For Qt 4, you need the following helper:
// Qt 4 only
struct FunctorSlot : public QObject {
Q_OBJECT
public:
std::function<void()> callable;
template <typename Fun>
FunctorSlot(Fun && fun, QObject * parent = {}) :
QObject{parent}, callable{std::forward<Fun>(fun)} {}
Q_SLOT void call() {
callable();
}
};
Possible solution:
QApplication a(argc, argv);
QDialog dlg;
QTimer::singleShot( &dlg, 0, SLOT(exec()) );
return a.exec();
It will work well. First - application event loop will be started. Then dialog event loop will be executed. After closing of dialog, both dialog and application loop will be finished. Application loop will be terminated automatically (by default), when last window is closed.
But, as noted by #thuga - there are no reason to call exec(). It is enough to call show() method.

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.

QSound doesn't work in if statement

This doesn't work:
QString directory = "";
int main(int argc, char *argv[])
{
QString boo = getDir();
if(!boo.isEmpty()) {
directory = boo;
QSound s1(directory);
QApplication a(argc, argv);
MainWindow w;
s1.play();
// MainWindow shows fine but QSound doesnt work at all
} else {
//somethingelse
}
}
But this works fine.
QString directory = "";
int main(int argc, char *argv[])
{
QString boo = getDir();
if(!boo.isEmpty()) {
directory = boo;
QApplication a(argc, argv);
MainWindow w;
} else {
//somethingelse
}
QSound s1(directory);
s1.play();
}
The question is - What's wrong with my first example? i have no idea to be honest.
I tried many times and it still doesn't work. What should i do to fix it?
Problem is simply, your QSound instance goes out of scope and gets destructed at the end of "then" block, and sound stops playing before you hear anything.
Move the definition out of the "then" block, before it. Then just start playing it in "then" block.

Resources