Constructing / destructing QApplication causes QWebView to mess up rendering of HTML - c++

We need to create & destroy instances of QApplication, as we want to use Qt in a plug-in to an existing host application.
void multiQT()
{
int argc = 0;
QApplication app(argc, NULL);
QWebView view;
view.setHtml("<html><head><title>Title</title></head><body><h1>Hello World</h1></body></html>");
view.show();
app.exec();
}
main(int argc, char** argv)
{
// First call works fine, QWebView renders the HTML just fine
multiQT();
// Second call fails, QWebView strips HTML tags from HTML text and
// and renders "TitleHello World"
multiQT();
}
When showing the QWebView the second time, it does not render the HTML properly. Do we need to do some additional (re-)initializations in QApplication or QWebView?

You might have run into something that has been very lightly tested, the QApplication object among others creates/holds some of the rendering context information of widgets, I don't think it was ever planned for people to take it down and put it back up again. There might be some static content that does not get reinitialised correctly when somebody tries what you are trying to do.

You are supposed to have only 1 QApplication object, and only 1 call to exec(). Maybe you should try this.
QWebView * multiQT()
{
QWebView *view = new QWebView;
view->setHtml("<html><head><title>Title</title></head><body><h1>Hello World</h1></body></html>");
view->show();
return view;
}
main(int argc, char** argv)
{
QApplication app(argc, NULL);
QWebView * web0 = multiQT();
QWebView * web1 = multiQT();
app.exec();
}

Related

qt QApplication doesn't Display Realtime data

I have two separate c++ projects that run simultaneously and exchange information between them using TCP/IP.
The names of those two projects are "World" and "Platform". To display Data and output in Real time, I have created a Qapplication object inside "World" class.
(I do not want to use Qt forms to create QGprahics view I just want to code it). TCP/IP works without any problems.
here is my code:
main.cpp:
#include "QTcpServer"
#include "QTcpSocket"
#include "QApplication"
#include "QGraphicsScene"
#include "QTime"
World::World()
{
WorldSettings settings;
Sys = new Dynamics(settings);
}
void World::run()
{
while (!time->finished())
{
if (controlStatus)
{
sendWorldData();
getPlatformData();
}
displayData();
}
int World::displayData()
{ char *argv[] = {"a", "arg1", "arg2", NULL};
int argc = sizeof(argv) / sizeof(char*) - 1;
QApplication a(argc, argv);
QGraphicsScene * scene = new QGraphicsScene();
// create an item to put into the scene
QGraphicsRectItem * sag = new QGraphicsRectItem();
sag->setRect(0,0,10,15);
view->show();
return a.exec();
}
with run this file, in first step time, the widget viwe is display and then the program stops running.(In other words, the program stops in the first iteration).
I expect the code I'm writing to behave like this:First, the widget is displayed and then the data are displayed in the corresponding graphic items, number displays, etc. and in every iteration of the code, these display objects are updated. In other words, I have a real time program that I need to display it's output data in real time.

QDialog closing on it's own, how can i fix it?

My class names is like (what it does)_(type) for example: reg_QDialog
Here is code of an executing dlg and if Accepted creating QMainWindow:
if(log_dlg->exec() == QDialog::Accepted)
{
find_wnd = new find_QMainWindow();
find_wnd->show();
}
log_dlg has 2 btns: "Enter" (here is the accept result) and "Reg" (opens a new dlg)
"Enter" and "Reg" code is here:
void log_QDialog::on_btn_enter_clicked()
{
this->accept();
}
void log_QDialog::on_btn_reg_clicked()
{
reg_QDialog *reg_dlg = new reg_QDialog();
this->hide();
if(reg_wnd->exec() == QDialog::Accepted)
{
//code
}
this->show();
}
So, here is the problem:
Step by step:
1) run the prog //it starts with dlg_log
2) "Reg" //creating dlg_reg
3) accept dlg_reg //returning to dlg_log
4) "Enter" //trying to create QMainWindow
QMainWindow is not created, and the app just closed
After "returning"(it's, actually, just hiding and then showing) from the reg_dlg and pushing btn with accept result it does nothing! It just closes the programm, but it had to show QMainWindow!
All real code of main.cpp:
#include "log_window_root.h"
#include "find_mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
log_window_root * log_wnd;
find_mainwindow * find_wnd;
log_wnd = new log_window_root();
log_wnd->setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
log_wnd->setModal(true);
if(log_wnd->exec() == QDialog::Accepted)
{
find_wnd = new find_mainwindow();
find_wnd->setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);
find_wnd->show();
}
return a.exec();
}
You are a operating a bit beyond the limits of Qt. Looking at the documentation:
Generally, no user interaction can take place before calling exec().
As a special case, modal widgets like QMessageBox can be used before
calling exec(), because modal widgets call exec() to start a local
event loop.
Testing your code on Mac OS will give you the dreaded warning
modalSession has been exited prematurely - check for a reentrant call
to endModalSession
which shows, that you are working on thin ice and your code will break any time.
Consider reworking your code so that the MainWindow comes up and then show your dialogs. If you want to go on with the Dialog sequence, then remove the hide()/show() pair from on_btn_reg_clicked (these calls mess up your event loops).
QApplication exits and close when the last window has been closed.
You can discard this by setting QApplication::quitOnLastWindowClosed property to false.
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(false);
You may want to revert it to it's previous state when your job is done with those dialogs.
As #Jens mentioned in the other answer to your question, this is will break evenloop at some point and QApplication exits before even a.exec() being called. So, you can also create a zero width/height or off-screen QWidget as a parent of your dialogs. A QSplashScreen is also a good candidate for this. All your dialogs should be your splash screen children. At last, you can finish your splash screen by calling QSplashScreen::finish.
[Re-posting from duplicate-closed question since the top banner on it may cause people to skip that question entirely, and IMHO this one doesn't have a good answer.]
Here's a very simple example of showing a dialog before a QMainWindow. The dialog simply presents the option of starting the main app or not. They key points are that the QDialog portion happens before any other widgets are created (eg. QMainWindow here), and the app (main()) exits before that if needed. No reason to keep the QDialog around after it is used, so I create it on the stack and delete afterwards.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog *d = new QDialog();
QPushButton *pbYes = new QPushButton("Would you like to play a game?", d);
QPushButton *pbNo = new QPushButton("Get me out of here!", d);
QObject::connect(pbYes, &QPushButton::clicked, [d]() { d->done(QDialog::Accepted); });
QObject::connect(pbNo, &QPushButton::clicked, [d]() { d->done(QDialog::Rejected); });
d->setLayout(new QVBoxLayout);
d->layout()->addWidget(pbYes);
d->layout()->addWidget(pbNo);
const int ret = d->exec();
delete d;
if (ret == QDialog::Rejected)
return 0;
QMainWindow mw;
mw.setCentralWidget(new QLabel("Welcome to the Game!", &mw));
mw.show();
return a.exec();
}

QML application

My program has two modes GUI(on qml) and no GUI(command line).What code I must write for changing mode by passing argument in cmd
for example if I pass nameofapp.exe -no-gui must be work no-gui version
for simple qt/c++ application we have this code
QCoreApplication* createApplication(int &argc, char *argv[])
{
for (int i = 1; i < argc; ++i)
if (!qstrcmp(argv[i], "-no-gui"))
return new QCoreApplication(argc, argv);
return new QApplication(argc, argv);
}
int main(int argc, char* argv[])
{
QScopedPointer<QCoreApplication> app(createApplication(argc, argv));
if (qobject_cast<QApplication *>(app.data())) {
// start GUI version...
} else {
// start non-GUI version...
}
return app->exec();
}
It's from documentation,I want such of this for qml
OS is windows 7 ultimate but I don't think that it's depends on OS
You need at least one top level QObject per application type which will "make things happen" in the main event loop.
Assuming that you have made a clear separation of concern between the view and the backend (eg MVC), you will have 3 classes (which are QObject) :
MyAppBackend which does the actual work
MyGUIMainWindow which manage GUI input\outpout.
MyCLIMainObject which manage command line input\outpout
Each one should have a method to start doing work. For instance just showing a widget is how simple Qt apps start.
int main()
{
QApplication app;
MyGUIMainWindow window;
window.show();
return app.exec();
}
window.show() will queue an event which will be processed when app.exec(). is executed.
You need to do the same with a function which either post an event or emit a signal.
int main(int argc, char* argv[])
{
QScopedPointer<QCoreApplication> app(createApplication(argc, argv));
MyAppBackend backend;
backend.startDeffered();
if (qobject_cast<QApplication *>(app.data())) {
// start GUI version...
MyGUIMainWindow* window = new MyGUIMainWindow(0,...);
window->show();
} else {
// start non-GUI version...
MyCLIMainObject* cliobj = new MyCLIMainObject(0,...);
cliobj->showCLi();
}
return app->exec();
}

QObject::moveToThread: Widgets cannot be moved to a new thread

My IDE Qt 5.0.1, platform Linux
i have a problem about set widgets to window.(My opinion)
this is my main.cpp->
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QThread cThread;
MainWindow w;
w.doSetup(cThread);
w.moveToThread(&cThread);
cThread.start();
if(cThread.isRunning())
{
qDebug() << " Thread is Running...";
}
w.show();
return a.exec();
}
this is doSetup() method->
void MainWindow::doSetup(QThread &mainThread)
{
QObject::connect(&mainThread, &QThread::started, this, &MainWindow::activeLoopMainC);
}
i checked my signal-slot mechanism and it works.
slot method->
void MainWindow::activeLoopMainC()
{
qDebug() << " Signal-Slot structure working successfully..";
mainThreadProc((void*)(instAddr));
}
i call a function from my main.c by this slot method.
In debugging there is no problem about working codes. But my window is blank. there is only frame.
i receive an error message: QObject::moveToThread: Widgets cannot be moved to a new thread
How can i solve this problem?
Thank you in advance for your answers.
You can't move widgets into another thread - in order to keep user interface responsive, Qt needs to do all GUI work inside main thread.
If you have background work to do, then move background worker to other thread, and not the user interface.

Qt process stays in memory after application closes

i have simple application that start QDialog from its main like this :
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(resources);
QApplication app(argc, argv);
QCoreApplication::setApplicationName(APP_NAME);
QCoreApplication::setApplicationVersion(APP_VERISON);
QCoreApplication::setOrganizationDomain(APP_DOMAIN);
app.setStyle("WindowsXP");
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
AuthenticationDialogContainer *pAuthenticationDialogContainer = new AuthenticationDialogContainer();
if(pAuthenticationDialogContainer->exec() != QDialog::Accepted ) {
return 0;
}
return app.exec();
}
when its pass the end of the application that is after app.exec() and the application doing what is suppose to do . when i open the windows xp task manager i see that the process is still in memory and i need manually kill it . how can i prevent it from happening ?
QDialog::exec is a blocking call: this code show and close the dialog before the QApplication start.
You can use QDialog::show and handle the return code in QDialog::accept method.