I am using the Urho3D engine with Qt for an application. The problem is that both Urho3D and QApplication require to be ran from main(). For now I am using it in separate processes but IPC makes it complicated.
Is there any way to solve this issue? Thanks
My platform is Urho3D 1.5, Qt 4.71 and Windows 7 x64 and VS2015 (C++)
I'm new to both c++ and Urho3D, but I've successfully achieved it.
Simple code, haven't had further test:
awidget.h:
#ifndef AWIDGET_H
#define AWIDGET_H
#include <QWidget>
#include <QPushButton>
#include <Urho3D/Engine/Application.h>
class aWidget : public QWidget
{
Q_OBJECT
public:
explicit aWidget(QWidget *parent = 0)
{
QPushButton *button = new QPushButton(this);
connect(button, SIGNAL(clicked()), this, SLOT(pressed()));
}
public slots:
void pressed()
{
Urho3D::Context* context = new Urho3D::Context();
Urho3D::Application *application = new Urho3D::Application(context);
application->Run();
}
};
#endif // AWIDGET_H
main.cpp:
#include <QApplication>
#include <awidget.h>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
aWidget *widget = new aWidget();
widget->show();
return app.exec();
}
By the way, I'm using Qt 5.9.0
So the answer is quite simple. Instead of running QApplication by calling
app->exec();
it is needed to manually and regularily call this from your main loop:
app->processEvents();
This will take care that all events used by Qt are processed and QApplication will respond accordingly.
Example:
#include <QApplication>
#include <awidget.h>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
bool shallrun = true;
aWidget *widget = new aWidget();
widget->show();
while (shallrun)
{
app->processEvents();
...
}
...
}
Related
I'd like to show and then close a dialog after 5 seconds. The dialog needs to be automatically resized (horizontally and vertically) based on the content of a label. Here is my code:
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QTimer>
void notify (int intTime=1000)
{
QDialog notify;
notify.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
notify.setWindowFlag(Qt::FramelessWindowHint);
QLabel *lbl = new QLabel(¬ify);
lbl->setText("This is a test This is a test This is a test This is a test This is a test This is a test This is a test");
QApplication::processEvents();
notify.adjustSize();
QTimer::singleShot(intTime, ¬ify, SLOT(close()));
notify.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
notify(5000);
exit(0);
// return a.exec();
}
It does not not expand the dialog based on the label size. Here is how it looks:
How can I fix it? (Please also let me know if there is better way of doing this.)
I am using Qt5 in Linux.
Since you have not used a QLayout the QLabel will be displayed as large as you can, a possible request is to change the size of QDialog to the recommended size of QLabel with sizeHint():
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QTimer>
void notify (int intTime=1000)
{
QDialog notify;
notify.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
notify.setWindowFlag(Qt::FramelessWindowHint);
QLabel *lbl = new QLabel(¬ify);
lbl->setText("This is a test This is a test This is a test This is a test This is a test This is a test This is a test");
QApplication::processEvents();
notify.resize(lbl->sizeHint());
QTimer::singleShot(intTime, ¬ify, SLOT(close()));
notify.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
notify(5000);
exit(0);
// return a.exec();
}
The other possible solution is to use a QLayout:
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QTimer>
#include <QVBoxLayout>
void notify (int intTime=1000)
{
QDialog notify;
QVBoxLayout *lay = new QVBoxLayout(¬ify);
//notify.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
notify.setWindowFlag(Qt::FramelessWindowHint);
QLabel *lbl = new QLabel;
lay->addWidget(lbl);
lbl->setText("This is a test This is a test This is a test This is a test This is a test This is a test This is a test");
QApplication::processEvents();
QTimer::singleShot(intTime, ¬ify, SLOT(close()));
notify.exec();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
notify(5000);
exit(0);
// return a.exec();
}
I want to use layout in qt5, but In Visual Studio 2015 the layout does not work?
Here is my code:
layout.h code
#ifndef LAYOUT_H
#define LAYOUT_H
#include <QtWidgets/QMainWindow>
#include "ui_layout.h"
class layout : public QMainWindow
{
Q_OBJECT
public:
layout(QWidget *parent = 0);
~layout();
private:
Ui::layoutClass ui;
};
#endif // LAYOUT_H
main.cpp
#include "layout.h"
#include <QtWidgets/QApplication>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QHBoxLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
layout w;
QHBoxLayout hb;
QPushButton b("button 0");
QPushButton b1("button 1");
hb.addWidget(&b);
hb.addWidget(&b1);
w.setLayout(&hb);
w.show();
return a.exec();
}
Here is my result:
How to fix this problem?
QMainWindow is a special widget since it has default widgets like QStatusbar, QMenuBar, etc. When working with this widget we must place the new elements in the centralWidget.
So we must assign a widget that will be our centralWidget, and then to this we add the layouts as shown below:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
layout w;
w.setCentralWidget(new QWidget);
QHBoxLayout hb;
QPushButton b("button 0");
QPushButton b1("button 1");
hb.addWidget(&b);
hb.addWidget(&b1);
w.centralWidget()->setLayout(&hb);
w.show();
return a.exec();
}
I am new to QT GUI programming.
I am trying to test switching two mainwindows continously by using show and hide.
I have created a simple code in main.cpp
main(){
QApplication a(argc , argv)
Mainwinodw1 *window1 = new Mainwindow1();
Mainwinodw1 *window2 = new Mainwindow2();
for (;;)
{
window1->show();
delay();
window1->hide();
window2->show();
delay();
window2->hide();
}
return a.exec();
}
The test can display the windows only one time , but duirng the second iteration they dont show and hide.
Can somebody help to fix this.
Try to use Qt timers instead of hardcoded delay function.
main.cpp file:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Mainwindow1 *window1 = new Mainwindow1();
Mainwindow2 *window2 = new Mainwindow2();
WindowSwitcher ws(window1, window2, 2000);
window1->show();
return a.exec();
}
WindowSwitcher source code:
#include "windowswitcher.h"
#include <QTimer>
WindowSwitcher::WindowSwitcher(QMainWindow *w1, QMainWindow *w2, int delay) : QObject(), window1(w1), window2(w2)
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(switchWindow()));
timer->start(delay);
}
void WindowSwitcher::switchWindow()
{
if (window1->isVisible())
{
window1->hide();
window2->show();
}
else
{
window1->show();
window2->hide();
}
}
WindowSwitcher header file:
#include <QObject>
#include <QMainWindow>
class WindowSwitcher : public QObject
{
Q_OBJECT
public:
explicit WindowSwitcher(QMainWindow *w1, QMainWindow *w2, int delay);
private:
QMainWindow *window1;
QMainWindow *window2;
public slots:
void switchWindow();
};
This question already has answers here:
C++ Qt signal and slot not firing
(3 answers)
Closed 8 years ago.
I am very new to Qt and it looks like i have some very basic misunderstanding about how this library works. I am currently reading a book by m. Schlee but i do not want to continue until i do understand how to make this simple program work.
#include <QtWidgets>
#include <QApplication>
#include <QStackedWidget>
#include <QPushButton>
#include <QObject>
struct wizard : public QObject
{
QStackedWidget* p;
wizard(QStackedWidget* pp) : p(pp) { }
public slots:
void change()
{
int to = p->currentIndex();
if (to == p->count() - 1)
to = 0;
else
++to;
emit chIndex(to);
}
signals:
void chIndex(int);
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStackedWidget qsw;
QPushButton qpb("magic");
qsw.resize(500, 500);
qsw.move(500, 300);
qsw.setWindowTitle("test qsw");
qpb.move(330, 300);
qpb.setWindowTitle("test qpb");
QWidget* pw1 = new QWidget();
QPalette pal1;
pal1.setColor(pw1->backgroundRole(), Qt::blue);
pw1->setPalette(pal1);
pw1->resize(500, 500);
pw1->setAutoFillBackground(true);
QWidget* pw2 = new QWidget();
QPalette pal2;
pal2.setColor(pw2->backgroundRole(), Qt::yellow);
pw2->setPalette(pal2);
pw2->resize(500, 500);
pw2->setAutoFillBackground(true);
qsw.addWidget(pw1);
qsw.addWidget(pw2);
wizard stupidity(&qsw);
QObject::connect(&qpb, SIGNAL(clicked()), &stupidity, SLOT(change()));
QObject::connect(&stupidity, SIGNAL(chIndex(int)), &qsw, SLOT(setCurrentIndex(int)));
qpb.show();
qsw.show();
return a.exec();
}
The idea is to launch 2 separate windows: one with painted background, and another with button that changes color (blue->yellow->blue->.. etc).
They appear, but nothing happens if i press the button. Please help.
Except for struct being a class and a missing Q_OBJECT macro the code is fine
Try the following:
create a main.h file having this content:
#ifndef MAIN_H
#define MAIN_H
#include <QObject>
#include <QStackedWidget>
class wizard : public QObject
{
Q_OBJECT
public:
QStackedWidget* p;
wizard(QStackedWidget* pp) : p(pp) { }
public slots:
void change()
{
int to = p->currentIndex();
if (to == p->count() - 1)
to = 0;
else
++to;
emit chIndex(to);
}
signals:
void chIndex(int);
};
#endif // MAIN_H
change your main.cpp to the following content:
#include <QtWidgets>
#include <QApplication>
#include <QPushButton>
#include <main.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStackedWidget qsw;
QPushButton qpb("magic");
qsw.resize(500, 500);
qsw.move(500, 300);
qsw.setWindowTitle("test qsw");
qpb.move(330, 300);
qpb.setWindowTitle("test qpb");
QWidget* pw1 = new QWidget();
QPalette pal1;
pal1.setColor(pw1->backgroundRole(), Qt::blue);
pw1->setPalette(pal1);
pw1->resize(500, 500);
pw1->setAutoFillBackground(true);
QWidget* pw2 = new QWidget();
QPalette pal2;
pal2.setColor(pw2->backgroundRole(), Qt::yellow);
pw2->setPalette(pal2);
pw2->resize(500, 500);
pw2->setAutoFillBackground(true);
qsw.addWidget(pw1);
qsw.addWidget(pw2);
wizard stupidity(&qsw);
QObject::connect(&qpb, SIGNAL(clicked()), &stupidity, SLOT(change()));
QObject::connect(&stupidity, SIGNAL(chIndex(int)), &qsw, SLOT(setCurrentIndex(int)));
qpb.show();
qsw.show();
return a.exec();
}
qmake doesn't work very well with Q_OBJECT macro directly in cpp file. Btw. run qmake after changes applied.
I would like to abort an application execution (done with Qt) with an error message in case there was a problem regarding it.
with abort(); it was not working with me.
Do you have any suggestions?
The simplest way is to exit the application's event loop with a non-zero result code, and show a message box afterwards. You can either re-spin the event loop manually, or let the messagebox's static method do it for you.
#include <QPushButton>
#include <QMessageBox>
#include <QApplication>
QString globalMessage;
class Failer : public QObject {
Q_OBJECT
public:
Q_SLOT void failure() {
globalMessage = "Houston, we have got a problem.";
qApp->exit(1);
}
};
int main(int argc, char ** argv) {
QApplication app(argc, argv);
QPushButton pb("Fail Me");
Failer failer;
failer.connect(&pb, SIGNAL(clicked()), SLOT(failure()));
pb.show();
int rc = app.exec();
if (rc) {
QMessageBox::critical(NULL, "A problem has occurred...",
globalMessage, QMessageBox::Ok);
}
return rc;
}
#include "main.moc"