QDialog window usage and exemples...
-
Could someone can write here a little exemple for call a QDialog window the best way ?
usually, i use (an dlearn) to go by ".exec()" for call it (like read on Qt afficial documentation exemples), but someone talk about "open()" and suggest that it is a better practice for stability of application. Also, i have a problem of stability maybe due to the practice of ".exec()" call.Please, if someone coudl write here a little exemple (or a link who give this exemple) of how to call the dialog window in model mode by this way and haw to handle the answer (accept and reject) for use it well, i would be really happy to learn this.
Thanks for your real help.
-
HI!
Usually you need to inherit your own dialog class from QDialog to customize it.
Set buttons, assign them values and so on.Exec() shows dialog in modal mode always. Open() unlike exec() may show dialog in non modal mode. Also see setModal(bool) funcion;
exec() return the code (Accepted or Rejected) if in dialog exists such buttons.
It seems like this in code
@MyDialog *myDialog=new MyDialog(this);
int result=myDialog->exec();if (result==QDialog::Accepted)
{
// some code
}
else
{
// some code
}
delete myDialog;
@ -
Hi Subst27, and thank you for your answer. I think this post could help you to if someone really answer to the question.
But i think you not understand well the question, because i know this way (like i write) allready and then, someone tell me that it is not a good way.
also, in your code, use of pointer and new instance like this is ok, but more easy to simply do:
@
MyDialog myDialog;
int result = myDialog.exec();
.
.
.
@but this is not what i ask for learn.
I ask if someone know the "good method" provide by Andre who consist to use ".open()" for modal call and NOT ".exec()".
And also provide an exemple around call and catch event from accepted and rejected by this way of call: ".OPEN()".i think the best one who can maybe help around this could be Andre, because it was him who tell this. I wait for his help, but an other one who know would be welcome to, for sure (and i am sorry about no exemple on Qt doc is writing around this...).
-
@MyDialog myDialog;
int result = myDialog.exec();@sure it's easy way in simple case :)
excluding cases when we need to manipulate dialog from another place. E.g. other thread. Sure dialog must be class member. Using pointer more universal may be. But this "another story altogether".
Well. I see you, will be waiting for Andre :)
-
i'm waiaitng for an answer to the question my friend...
Andre or you if you know, this is not a problem.
do you know the answer ? -
why you can't do some like this
in dialog set buttons and process signals pressed()
from slot connected to such signals emit you own signal connected to main window slot
signal dialogClosed(bool) in dialog
slot dialogClosed(bool) in windowafter emit signal call Accept() | Reject() to close dialog.
I understand problem carefully?
-
yes, it is right.
I'm many time confuse with this doc of Qt, and then, i learn more here when i can share with peoples who really use it.so, like you and some other, because i'm a beginner, read code of great exemple help me a lot.
-
moreover such signals are already declared.
Well I can write a little project with main window and dialog. I'm not so busy at time.
and moreover exists the easy way
Do u ready to wait a little time?
-
Ok, let me get into this again then. I was the one suggesting to use open() instead of exec(). It would have been nice stay in the same topic and not open a new one, as that would have provided the needed context.
[quote author="Subst27" date="1421130468"]
Open() unlike exec() may show dialog in non modal mode.
[/quote]That is simply not true, and it is says so right in the documentation for open():
[quote]
Shows the dialog as a window modal dialog, returning immediately.
[/quote]
So, open() results in a modal dialog, period.Using that method instead of spinning a local eventloop as exec() does yields the benefit of no suprises in your code path: when you call exec(), the code looks as if execution has stopped in right where you called it, and continues ones the dialog is closed. That is not quite the case: your application is still running, and in various ways it is possible that code is called that will do something that causes unexpected behaviour, perhaps even deleting the object that opened the dialog in the first place. Then what? In the majority of cases, this will of course not happen and everything will be fine. But it may be a cause of hard to track bugs. For instance: a few years ago, it turned out you could crash almost all KDE applications due to this very issue, by using DBUS when a dialog was open.
To prevent that from happening, you can use the asychronous method supplied by using open() instead of the synchronous exec().
The simplest setup is like this:
@
void someFunctionThatShowsTheDialog()
{
...
MyDialog* dlg = new MyDialog(this);
//handle the result
connect(dlg, SIGNAL(finished(int)),
this, SLOT(handleMyDialogResult(int)));
//clean up dialog afterwards
connect(dlg, SIGNAL(finished()),
dlg, SLOT(deleteLater()));
dlg->open();
}void handleMyDialogResult(int result)
{
// do something with the result
// problem: no nice direct access to MyDialog itself
}
@That is: you will need to spread your code over more than one function. That is not optimal, especially if your code becomes more complex. If you need access to MyDialog itself, you end up with either having to set a member variable or (not recommended) using the sender() function and a cast to retreive it.
C++/11 & Qt5 to the rescue...
@
void someFunctionThatShowsTheDialog()
{
...
MyDialog* dlg = new MyDialog(this);
dlg->open();
connect(dlg, SIGNAL(finished(int)), [dlg, this](int result) {
if (result == QDialog::Accepted) {
//do whatever you need to do, even access the instance via the dlg pointer
}
dlg->deleteLater(); //we can nicely clean up too!
});
}
@Now, you simply use a lambda function to handle the result. That has some rather nice effects:
- The code to handle the result of the dialog is back where it belongs: with the dialog creation and showing itself. That makes it easier to follow what's going on.
- You can pass variables from the scope of the function where you defined the lambda available inside the lambda function itself. That makes it easy to get access to the dialog again to get more data from it.
- No need for a separate connection to clean up the dialog afterwards
- No pollution of your class API with added slots and member functions that are only used in the context of showing this one dialog from this one function.
-
you need to use Open instead Exec, but wanna get result code. It's a principle question.
Isn't it?
-
thanks Andre, yur explication is ok for me.
Also, i try it an ok... the QDialog window open fine.BUT, i have always the same problem crash application (really strange).
This not resolve the problem, but maybe it is a way for understand, because...
because when i call, inside these QDialog windows (like from every where) the QSqlQuery query, i do a query.exec().
Also, i see inside debug tool that it crash on sql driver use...
So maybe it is the same problem... of bad call.what do you think ?
is it possible to use same technic for call a query than for call a QDialog or everythings ?(again, thanks for your answer, i learn really a lot with you)
-
get the source code
how you declare the query and execute it ? -
in fact someone make me understand that there is no way to do same style for execute query.
For use QSqlQuery, i go by declare the database default access, and then declare a QSqlQuery. After, i use query.prepare(), and if need, query.bindValue(). after that, i do an query.exec() around condition for get back an eventuall error, and then a loop while(query.next()) for catch the datas.but also, in the first QDialog window, i use a QSqlQueryModel and use model->setQuery("SELECT...blablabla...");
i think that there is an internal conflict because debug gdb tell me that it crash on the postgresql drivers qsl library.
so... i try to find a solution...
-
maybe the solution is to not use QSqlQueryModel... but pfffff... i'm lazy and this tool is nice and if it will be impossible to trust the Qt tools and do all without model helper... why follow to use Qt and not just use WXWidget in fact ?
I just follow the exemples and this crash is really strange. In fact, i hope it is an error from my-self.
I hope also to find a solution without re-invent the wheel or have to big difficulties.
-
And you think that switching toolkit would solve SQL driver issues for you?
-
Subst27, thank you a lot for give some time for try to help.
Also, i give you some parts of my code.
like that you could have a look and see if there is something you like or dislike, or maybe could use for yourself, and maybe find a bad code.
this code is not clean... but some parts are considered as finished inside. -
Andre: i really don't know. i don't know because i can not understand why this issue occur.
If i caould be able to understand what's happen really, i will sure find a good solution (and maybe tuch the code of the driver). But i think this is not my level.I just try to understand at this step of my reflexion... and then, i see that when i call this from an other one QDialog window who not use QSqlQueryModel, there is no problem... so i think that maybe there is a problem inside the code of the QSqlQueryModel tool... but i'm really not sure, i just do a link by deduction.
-
for the part of code... this part of my open_project::on_projects_list_clicked() file has to be change by this:
@
void open_project::on_projects_list_clicked(const QModelIndex &index)
{
QString sformat = QString("dd/MM/yyyy %1 hh:mm:ss").arg(tr("à"));
name = model->record(index.row()).value("name").toString();
comment = model->record(index.row()).value("comment").toString();
ref_project = model->record(index.row()).value("refproject").toString();
date_create = model->record(index.row()).value("datecreate").toDateTime();
id = model->record(index.row()).value("id").toInt();
ui_open_project->label_name->setText(name);
ui_open_project->comment->setText(comment);
ui_open_project->ref_client->setText(ref_project);
ui_open_project->date_create->setText(date_create.toString(sformat));
if (id != 0)
locations_refresh();
ui_open_project->treeView_locations->setColumnHidden(1,true);
}
@ -
ok Andre, now i swith toolkit and not use QsqlQueryModel for popaulate my model for my QListView of the QDialog window who call the other...
And YES... this was the problem definitly.So... use QSqlQueryModel without some other use of query could crash the application. I had a good dedustive analyse of the problem. Impossible to use this tool, this tool is not "good" (execpt if you only use one QDialog maybe) and bugged.
But... what i can do for post a bug around this tool for Qt ?
Wich post could be positive bug report for help to find a solution for this tool can works good ? -
here is the modification of my code for be able to see the application works normally...
https://gist.github.com/anonymous/09985ba94fa765754193
if someone find why this QSqlQueryModel crash the application, and/or what kind of bug publication i can write, you would be welcome to teach this.
thank you for your help and teach.