Open a dialog from other than mainwindow
-
Using Qt Creator, 12.0.2, I create a simple Qt app with dialog, then create two additional dialogs, call them d2 and d3. Create each with the steps: File -> New File -> Qt -> Qt Designer Form Class
Add pushbuttons to the main dialog to open d2 and d3. Both work. Both dialogs are displayed. Call the main dialog “main” for convenience.
The Need
I need to show dialog d3 using a pushbutton in d2.
The Work So Far
Side note: I suspect this is a general concept question. If so, hopefully, there is no need to post all the source code from multiple files. If this presumption is wrong, I can post the code.
d2 needs the pointer to d3 to detect if d3 is open, but, the d3 pointer is in main, and d2 does not have a pointer to main or d3.
So, Add a function in main to push its “this” pointer from main to d2. To accomplish this task:
In d2.h in the public section add the declarations:QDialog * main_window_ptr = NULL; void set_main_dialog_pointer( QDialog * temp );
in d2.cpp add the function
void d2::set_main_dialog_pointer( QDialog * temp ) { main_window_ptr = temp; }
Go to mainwindow.cpp to the code used to open d2 and add one line of code:
void MainWindow::on_pb_open_d2_clicked(bool checked) { if( d2 == NULL ) d2 = new( QDialog ); d2->show(); d2->setWindowTitle( "dialog D2"); // add the below line d2->set_main_dialog_pointer( this ); // error states no member named “set_main_dialog_pointer’ in Qdialog. }
Understood, there is no such function in QDialog. But it does exist in object d2. As noted above, it is declared in the “public” section of d2.h
So in the header of mainwindow.h, and just to be certain, in mainwindow.cpp, add:#include “d2.h”
That line solicits the error message: Included header d2.h is not used directly.
Well, Yes, it is, its in the function a few lines down that looks like:d2->set_main_dialog_pointer( this );
The one with the error code proclaiming No member named “set_main_dialog_pointer.
The Question
What code must be added such that main will recognize the function in d2? If I can get the main dialog pointer into d2, and access to functions within main, then I think I can add the code to open d3.Is there a better way to provide d2 with the ability to open and show d3? Implied is the condition that if d3 already exists, then just show it rather than create a new copy.
-
The fact that only parts of your code are shown, makes it rather difficult to understand your problem.
d2
looks ambiguous to me. It seems to be aQDialog*
member ofMainWindow
, at least derived from the code inon_pb_open_d2_clicked()
.
It also seems to be a class name, derived from the existence ofd2.h
andd2.cpp
and the existence ofvoid d2::set_main_dialog_pointer( QDialog * temp )
.Maybe this class inherits from
QDialog
. That's hard to believe, because I can't see how it could in that case be initialized with a barenew QDialog
. Maybe it has some magic template constructor. But without code - how could I know.In any case, you should resolve the ambiguity by distinguishing class names and member names. Mixing those up is a highly error-prone anti-pattern. What is currently the
QDialog *d2
member ofMainWindow
, should be something liked2 *m_d2
, to make sure it has the typed2
, which makesset_main_dialog_pointer()
accessible.on_pb_open_d2_clicked()
would have to look like that:void MainWindow::on_pb_open_d2_clicked(bool checked) { if (!m_d2) m_d2 = new d2; m_d2->setWindowTitle( "dialog D2"); // better set the title before showing m_d2->show(); m_d2->set_main_dialog_pointer( this ); // error should be gone, provided d2 is implemented correctly. }
Just on a side note: Bare pointer members without a
QObject
parent are kinda discouraged. Better use a scoped type likestd::unique_ptr
. -
@Axel-Spoerl said in Open a dialog from other than mainwindow:
m_d2->set_main_dialog_pointer( this );
Isn't this also "anti-pattern"?
I don't think there is really a need of passing theMainWindow
parent to the dialog class.If I understand @Bryan-Kelly correctly, the whole case can be merged into this code
(just the crucial parts)// mainwindow.h private: Dialog_One *m_dialogOne; Dialog_Two *m_dialogTwo;
// mainwindow.cpp QPushButton * p1 = new QPushButton("open Dialog_One", this); QPushButton * p2 = new QPushButton("open Dialog_Two", this); // connect Button1 to create Dialog_One and Dialog_Two instance, // pass Dialog_Two with Dialog_One c'tor and open Dialog_One afterwards connect(p1, &QPushButton::clicked, this, [=](){ if (m_dialogOne) m_dialogOne->show(); else if (m_dialogTwo) { m_dialogOne = new Dialog_One(m_dialogTwo, this); m_dialogOne->show(); } else { m_dialogTwo = new Dialog_Two(this); m_dialogOne = new Dialog_One(m_dialogTwo, this); m_dialogOne->show(); } }); //connect Button2 to open Dialog_Two connect(p2, &QPushButton::clicked, this, [=](){ if (m_dialogTwo) m_dialogTwo->show(); else { m_dialogTwo = new Dialog_Two(this); m_dialogTwo->show(); } });
// Dialog_One.h Dialog_One(Dialog_Two *dialog = nullptr, QWidget *parent = nullptr); private: Dialog_Two *m_dialog;
// Dialog_One.cpp // show Dialog_Two instance // (the one which was created in MainWindow and passed to here connect(p, &QPushButton::clicked, this, [=](){ if (m_dialog) m_dialog->show(); });
-
@Pl45m4 said in Open a dialog from other than mainwindow:
Isn't this also "anti-pattern"?
It probably is. It's seldom a good idea to fiddle with pointer up the parental chain. There may be corner cases, where that's useful.
But as said before: How should we know without code? -
here is the code. Begin with the list of files that exist after the project has been created, then the two dialogs d2 and d3 have been created.
next is mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); // dialog d2 needs to have a pointer to d3 so if d3 is already // open it can just show it. Then d2 needs the ability to // inform main (as in mainwindow.h, this object) that d3 has been created. QDialog * get_d3_pointer(); void put_d3_pointer( QDialog * temp ); private slots: void on_pb_open_d2_clicked(bool checked); void on_pb_open_d3_clicked(); private: Ui::MainWindow *ui; QDialog * d2 = NULL; QDialog * d3 = NULL; }; #endif // MAINWINDOW_H
next is mainwindow.cpp
#include "mainwindow.h" #include "./ui_mainwindow.h" #include "qdialog.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pb_open_d2_clicked(bool checked) { if( d2 == NULL ) d2 = new( QDialog ); d2->show(); d2->setWindowTitle( "dialog D2"); // When dialog d2 is opened, copy the local 'this' pointer to d2 so that d2 can // determine if d3 has been created. // The next line has the message: No member named 'set_main_dialog_pointer' in 'QDialog' // True, but, object d2 has that function declared. This is to call it. d2->set_main_dialog_pointer( this ); } void MainWindow::on_pb_open_d3_clicked() { if( d3 == NULL ) d3 = new( QDialog ); d3->show(); d3->setWindowTitle( "dialog D3"); } // cannot get the above code to work so have not completed these items. QDialog * MainWindow::get_d3_pointer() { return d3; } void MainWindow::put_d3_pointer( QDialog * temp ) { d3 = temp; }
next is d2.h
#ifndef D2_H #define D2_H #include <QDialog> namespace Ui { class d2; } class d2 : public QDialog { Q_OBJECT public: explicit d2(QWidget *parent = nullptr); ~d2(); // The main dialog can call this function, provide its "this" pointer, // so this object, d2, can get the value of main's d3 pointer. void set_main_dialog_pointer( QDialog * temp ); private slots: void on_pb_open_d3_2_clicked(); QDialog * main_window_ptr = NULL; private: Ui::d2 *ui; QDialog * local_d3_ptr; }; #endif // D2_H
next is d2.cpp
#include "d2.h" #include "ui_d2.h" #include "mainwindow.h" d2::d2(QWidget *parent) : QDialog(parent) , ui(new Ui::d2) { ui->setupUi(this); } d2::~d2() { delete ui; } // This is the second push button that can create/open dialog d3. void d2::on_pb_open_d3_2_clicked() { // get main's pointer to d3. It may or may not be valid // The next line has the error message: // No member 'get_d3_pointer' in 'QDialog' // True, but that function is declared in mainwindow.h // which should be pointed to my main_window_ptr. local_d3_ptr = main_window_ptr->get_d3_pointer(); if( local_d3_ptr == NULL ) { local_d3_ptr = new( local_d3_ptr ); // next line has same errors noted a few lines up. main_window_ptr->put_d3_pointer( local_d3 ); } } void d2::set_main_dialog_pointer( QDialog * temp ) { main_window_ptr = temp; } // from post by Pl45m4 // changed m_dialog to match this code with d3, the pointer to the dialog // to be opened. Many errors here. The text of the first is: // A type specifier is required for all declarations. connect(p, &QPushButton::clicked, this, [=](){ if (local_d3) local_d3->show(); });
&&&&&&&&&&&&&&&&&&&&&&&&
files d3.h and d3.cpp have not yet been edited. The dialog has been opened from main window, but not from d2, which is the goal.mainwidow.ui has two pushbuttons as shown below, the upper left corner of that dialog
dialog d2 has just one added pushbutton, to open d3. It is named pb_open_d3_2
files d3.h, d3.cpp, and d3.ui have not been changed after being created by Qt Creator.
&&&&&&&&&&&&&&&&&
Finally, to restate the goal of this app: The main dialog has the ability to open and show dialog d3. That is just standard code. The goal is to provide dialog d2 with the ability to open and/or show dialog d3. -
@Bryan-Kelly said in Open a dialog from other than mainwindow:
Finally, to restate the goal of this app: The main dialog has the ability to open and show dialog d3. That is just standard code. The goal is to provide dialog d2 with the ability to open and/or show dialog d3.
Have you looked at my code? This it exactly what it does.
(Dialog_One
= your "d2",Dialog_Two
= your "d3")Edit:
@Bryan-Kelly said in Open a dialog from other than mainwindow:
// from post by Pl45m4
// changed m_dialog to match this code with d3, the pointer to the dialog
// to be opened. Many errors here. The text of the first is:
// A type specifier is required for all declarations.connect(p, &QPushButton::clicked, this, [=](){ if (local_d3) local_d3->show(); });
You can't throw pieces of code in at random.
Maybe I haven't explained properly.The connection belongs in the constructor of
d2
(to connect the button with the code between the curly brackets).
(-> called C++ Lambda )
I saved myself the effort of writing the each slot as separate function, but you can replace that with a regular function or slot.This, for example, can't work / produces your error respectively, because
d1
andd2
are actuallyQDialogs
(subsclasses) but only ad1
ord2
instance knows about the functions you have added.
With the code below (where you pass the pointers around), you pass the pointer asQDialog
type. Doesn't throw any error, because it's valid.
But it makes no sense.
Side note:
... unless you want to store a bunch of different subclasses from one general type in a single container:Say you have these classes and they all inherit from a "super" class called
Super
class A : public Super class B : public Super class C : public Super
To store their pointers in one container all together, you could do something like:
QList<Super *> container;
Now back to your issue.
Here is what you wrote:
void d2::set_main_dialog_pointer( QDialog * temp ) { main_window_ptr = temp; }
temp
andmain_window_ptr
areQDialog
pointers from now on (ind2
class) andQDialog
has no function likeget_d3_pointer()
.
So you get the error message as you write here// The next line has the error message: // No member 'get_d3_pointer' in 'QDialog' // True, but that function is declared in mainwindow.h // which should be pointed to my main_window_ptr.
I usually don't post complete projects, because the learning effect is not that high when looking at somebody else's code. Everybody has it's own style how you would solve things etc.
But this is the full code of the working example:MainWindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> class Dialog_One; class Dialog_Two; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Dialog_One *m_dialogOne; Dialog_Two *m_dialogTwo; }; #endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h" #include <QLayout> #include <QPushButton> #include "dialog_one.h" #include "dialog_two.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_dialogOne{nullptr} , m_dialogTwo{nullptr} { QWidget *w = new QWidget; QHBoxLayout *hbox = new QHBoxLayout(w); w->setLayout(hbox); QPushButton * p1 = new QPushButton("open Dialog_One", this); QPushButton * p2 = new QPushButton("open Dialog_Two", this); connect(p1, &QPushButton::clicked, this, [=](){ if(m_dialogOne) m_dialogOne->show(); else if (m_dialogTwo) { m_dialogOne = new Dialog_One(m_dialogTwo, this); m_dialogOne->show(); } else { m_dialogTwo = new Dialog_Two(this); m_dialogOne = new Dialog_One(m_dialogTwo, this); m_dialogOne->show(); } }); connect(p2, &QPushButton::clicked, this, [=](){ if(m_dialogTwo) m_dialogTwo->show(); else { m_dialogTwo = new Dialog_Two(this); m_dialogTwo->show(); } }); hbox->addWidget(p1); hbox->addWidget(p2); setCentralWidget(w); } MainWindow::~MainWindow() {}
Dialog_One.h
#ifndef DIALOG_ONE_H #define DIALOG_ONE_H #include <QDialog> #include "dialog_two.h" class Dialog_One : public QDialog { Q_OBJECT public: Dialog_One(Dialog_Two *dialog = nullptr, QWidget *parent = nullptr); ~Dialog_One(); private: Dialog_Two *m_dialog; }; #endif // DIALOG_ONE_H
Dialog_One.cpp
#include "dialog_one.h" #include <QPushButton> #include <QLayout> Dialog_One::Dialog_One(Dialog_Two *dialog, QWidget *parent) : QDialog{parent} , m_dialog{dialog} { setWindowTitle("Dialog_One"); setObjectName("Dialog_One"); QPushButton *p = new QPushButton("Show Dialog_Two", this); QHBoxLayout *hbox = new QHBoxLayout(this); hbox->addWidget(p); setLayout(hbox); connect(p, &QPushButton::clicked, this, [=](){ if (m_dialog) m_dialog->show(); }); }
Dialog_Two.h
, actually not modified. Just basicQDialog
subclass.#ifndef DIALOG_TWO_H #define DIALOG_TWO_H #include <QDialog> class Dialog_Two : public QDialog { Q_OBJECT public: Dialog_Two(QWidget *parent = nullptr); }; #endif // DIALOG_TWO_H
Dialog_Two.cpp
#include "dialog_two.h" Dialog_Two::Dialog_Two(QWidget *parent) : QDialog{parent} { }
-
in your mainwindow.h is
Dialog_one *m_dialogOne; dialog_Two *m_dialogTwo;
I don't know what Dialog_One and Dialog_Two are.
I presume they represent the two dialogs I created and named d2 and d3.
Those have already been created and are in mainwindow.h in the formatQDialog * d2 = NULL; QDialog * d3 = NULL;
Switch to mainwindow.cpp. The code I detect as relevant is
QPushButton * p1 = new QPushButton("open Dialog_One", this); QPushButton * p2 = new QPushButton("open Dialog_Two", this);
Presume also that this belongs in the constructor for main, my shorthand for mainwindow.h, .cpp, and .ui
That seems to present a problem because as soon as the constructor completes those private pointers named p1 and p2 no longer exist. So back up to mainwindow.h and declare the pointers in there. Add the include while at it.
That constructor now looks like this:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QPushButton * p1 = new QPushButton("open Dialog_One", this); QPushButton * p2 = new QPushButton("open Dialog_Two", this); }
Next is the function:
connect(p1, &QPushButton::clicked, this, [=]() { }
I don't understand that. I don't know what is intended by the [=], an optional = character and maybe something else? Qt Creator does not approve of it.
A google search provided the format:
int connect( int socket, const struct sockaddr *address, socklen_t address_len);
argument 1 is "int socket", but the first argument used is p1, a pointer, and pointers don't go into a standard int.
argument 3 is "socklen_t address_len" and looks like the length of an address. The use of "this" does not seem to meet that need.
This appears critical and I must stop here and request clarification.
Meanwhile, I will be attempting to implement the code provided later in the post and see what happens. I have some events in progress at home so this may take me a couple of hours.
Thank you for your time and patience. -
@Bryan-Kelly said in Open a dialog from other than mainwindow:
in your mainwindow.h is
Dialog_one *m_dialogOne;
dialog_Two *m_dialogTwo;I don't know what Dialog_One and Dialog_Two are.
I presume they represent the two dialogs I created and named d2 and d3.
Those have already been created and are in mainwindow.h in the formatQDialog * d2 = NULL;
QDialog * d3 = NULL;Can you spot any difference there? Among other things, this is one of the reasons why your code is condemned to fail/throw errors.
@Pl45m4 said in Open a dialog from other than mainwindow:
Have you looked at my code? This it exactly what it does.
(Dialog_One = your "d2", Dialog_Two = your "d3")Here I've written what the Dialogs are
@Bryan-Kelly said in Open a dialog from other than mainwindow:
Switch to mainwindow.cpp. The code I detect as relevant is
QPushButton * p1 = new QPushButton("open Dialog_One", this); QPushButton * p2 = new QPushButton("open Dialog_Two", this);
This is not relevant. I created the buttons you've added with QtDesigner by code, because I don't use Designer.
@Bryan-Kelly said in Open a dialog from other than mainwindow:
Presume also that this belongs in the constructor for main, my shorthand for mainwindow.h, .cpp, and .ui
You can see in my complete code example that it belongs indeed in
MainWindow::MainWindow()
(constructor forMainWindow
).
Themain.cpp
has/needs no constructor, since it's not a class.@Bryan-Kelly said in Open a dialog from other than mainwindow:
That seems to present a problem because as soon as the constructor completes those private pointers named p1 and p2 no longer exist. So back up to mainwindow.h and declare the pointers in there.
They don't need to. I've created the buttons, added them to
MainWindow
'scentralWidget
- layout, so they will be visible on the screen (as part of the main windowMainWindow
). Then I connected what should happen on click (via lambda connections) and that's it.
To make this example work, you don't need any further access to them.
And since they are now part of theQObject
tree, they get deleted when their parent is (i.e. theMainWindow
).@Bryan-Kelly said in Open a dialog from other than mainwindow:
I don't understand that. I don't know what is intended by the [=], an optional = character and maybe something else? Qt Creator does not approve of it.
Regarding this and the other questions,
Please re-read my answer above, I've edited it multiple times now. Everything is explained there.
@Bryan-Kelly said in Open a dialog from other than mainwindow:
A google search provided the format:
int connect( int socket, const struct sockaddr *address, socklen_t address_len);
You probably picked the wrong page here. This doesn't look like a Qt connection.
Theconnect(....)
function is used in many frameworks, software/libraries.Here is the correct one:
This section also includes a C++ lambda connection as I have used.
(4th code snippet) -
@Pl45m4 said in Open a dialog from other than mainwindow:
This is not relevant. I created the buttons you've added with QtDesigner by code, because I don't use Designer.
First, your post represents some significant changes in how I do things. I am not ignoring, just going slow. We have home renovations in progress slowing me down considerably.
As quoted you don't use Designer. I presume that is the tool used to create dialogs with drag and drop. To my opinion that saves a lot of code needed to create and placing all the user tools. If I understand correctly, you write the code to place each tool. Is there a simple reason for doing this rather than using Designer?
Thank you for your time and patience.
-
@Bryan-Kelly hi,
There are several reasons:
- less tools to use (Designer and uic)
- all code in a single place (with Designer you have a separate file generated)
- personally, I am faster at writing a UI than doing drag and drop with Designer
Note that I am not against Designer, it just does not fit how I am used to code GUIs.
From a pure forum point of view, it's less code to create a minimal reproducer.
-
I apologize, but I cannot detect the answer I need in the replies provided so far, so here an an attempt at simplifying. The core question is so simple in concept, but it takes so much to set the stage to ask the question.
Create a project with two dialogs. The first dialog is created as the initial project is created, the second dialog is added. In the main project add these lines of code:
int main_x = 1; // in file mainwindow.h ... int MainWindow::get_x( return main_x ); // in file mainwindow.cpp
In the added dialog, create a pushbutton, and in its on_clicked() function, call that function in mainwindow.cpp.
local_x = MainWindow->get_x();
The problem
I cannot find the name of the instance, (the name of the object instantiated when the app is run) such that its functions can be called from the second dialog. What replaces that word: MainWindow-> ?Thanks again for your time and patience.
-
@Bryan-Kelly said in Open a dialog from other than mainwindow:
The core question is so simple in concept, but it takes so much to set the stage to ask the question.
Create a project with two dialogs. The first dialog is created as the initial project is created, the second dialog is added. In the main project add these lines of code:
int main_x = 1; // in file mainwindow.h ... int MainWindow::get_x( return main_x ); // in file mainwindow.cpp
Is
main_x
the simplification of your dialog classesdx
(d1, d2, d3 or whatever you call them)?The problem
I cannot find the name of the instance, (the name of the object instantiated when the app is run) such that its functions can be called from the second dialog. What replaces that word: MainWindow-> ?It's better to choose a "top-down" approach, than a "bottom-up". The
MainWindow
obviously has to know about the dialogs, and by design it makes more sense to only do what's really needed in the child dialogs. Let the parent (theMainWindow
) manage/delegate the childs (the dialogs), not the other way round.For your design idea to work, you would need to share the pointer to the
MainWindow
object with all its childs (dialogs). Then you can call the functions from there.
But this is not recommended.To hold onto your example with the
int x
, even though I assume you are trying to figure out how to deal with your dialog instances:There are basically two ways of retrieving a value from a dialog, using the signal&slot mechanism or using get functions.
But as I've said above, usually theMainWindow
would call the dialog's function to retrieve some value (e.g. yourint x
, whose value might come from an user input) and not the dialog calls a function from it's parent to actively "get" a value.Doing it the other way around is a bad design that may work, but can lead to more problems later or overcomplicate the structure of your application because then everything is tightly coupled and you have to be careful with the lifetime and deletion of almost everything to avoid crashing your app.
So to retrieve a value FROM a dialog, you can do something like:
int m_x; int MyDialog::getX() const { return m_x; }
{ MyDialog dlg; dlg.show(); int xFromDialog = dlg.getX(); }
This works for modeless dialogs and only to get a value from them.
To get your data into your dialog, do it as I did here:@Pl45m4 said in Open a dialog from other than mainwindow:
m_dialogTwo = new Dialog_Two(this); m_dialogOne = new Dialog_One(m_dialogTwo, this); // I passed "data" = d2 pointer to d1 m_dialogOne->show();
Pass data to it with the dialogs constructor... but don't pass the whole
MainWindow
.
Thanks to the Meta-Object system, you actually have access to everyQObject
s parent usingparent()
.
The second parameterthis
makesMainWindow
a direct parent ofDialog_One
.
But this is not save to use since it might change.The simplification with
int
would look like:
(re-using my dialog subclass from previous post)// dialog_one.h Dialog_One(int x = 0, QWidget *parent = nullptr); private: int m_x; // dialog_one.cpp Dialog_One::Dialog_One(int x, QWidget *parent) : QDialog{parent} , m_x{x} // assign x from constructor to private int member variable { } // Usage // mainwindow.cpp int main_int = 42; Dialog_One *myDialog = new Dialog_One(main_int, this);
There is no need ever to pass the whole parent instance to a child.
Feed them the data they need to work, then wait for the "callbacks" (like Qt signals) or retrieve the data manually (call from parent) using get-functions.Little modal (blocking) dialog example:
Assume the dialog has an input field for data like
Age
and you want to pass this to yourMainWindow
after the user clicks OK ("accepts" the dialog).// dialog.h int getAge() const { return m_age; } // mainWindow.cpp { // some scope Dialog dlg; if (dlg.exec() == QDialog::Accepted) { int ageFromDialog = dlg.getAge(); qDebug() << "The dialog contains age value: " << ageFromDialog; } }
-
@Pl45m4 said in Open a dialog from other than mainwindow:
Is main_x the simplification of your dialog classes dx (d1, d2, d3 or whatever you call them)?
There may be something in the question that I don't understand, but I think: No, its just an integer declared at what I think of as the top level of my application.
A term. I am using "main" to indicate the code that is first created when an application is created. If I take the defaults the file names used are mainwindow.h, main.cpp, mainwindow.cpp, and mainwindow.ui. So I have been using "main" to refer to the core of the app. The core that launches and anchors everything else.
I will have multiple dialogs that each do some things, and some of the results of those dialogs need to get back to main. I would prefer that the dialogs be able to send such data to main rather than waiting for the user to ask for the data with a button click. Then other dialogs will need that information and should be able to fetch it rather than waiting for the user to click a button in main and send it to various dialogs.
Ok, so a strategy change. Create a class to serve as a repository for shared data. Call it "repo" for repository. Keep the data private. Provide public get and put functions that dialogs can access. This class will not do any processing, just serve as a repository for shared data.
Is this a more reasonable approach?
-
@Bryan-Kelly said in Open a dialog from other than mainwindow:
@Pl45m4 said in Open a dialog from other than mainwindow:
Is main_x the simplification of your dialog classes dx (d1, d2, d3 or whatever you call them)?
There may be something in the question that I don't understand, but I think: No, its just an integer declared at what I think of as the top level of my application.
Yes, I wasn't asking what
main_x
is ( I know/can see that), I was rather asking about its meaning in your program / for you.
The topic is named "Open a dialog from other than mainwindow", I made couple suggestions with full examples and code snippets, and now there's anInteger
you want to pass somewhere, which I said, works the same as if you would pass any other pointer or data to your dialog.A term. I am using "main" to indicate the code that is first created when an application is created. If I take the defaults the file names used are mainwindow.h, main.cpp, mainwindow.cpp, and mainwindow.ui. So I have been using "main" to refer to the core of the app. The core that launches and anchors everything else
As said above, it's not about why the variable is called like this. More like what are you trying to do with it and why.
So I was wondering if you just simplified your code for your better understanding... and went from passing aQDialog
pointer to passing anint
... that's why I was asking.I will have multiple dialogs that each do some things, and some of the results of those dialogs need to get back to main. I would prefer that the dialogs be able to send such data to main rather than waiting for the user to ask for the data with a button click. Then other dialogs will need that information and should be able to fetch it rather than waiting for the user to click a button in main and send it to various dialogs.
Understood. But the data doesn't "travel" from one dialog to another or to your
MainWindow
by itself. There needs to be some (user inter-)action going on.
For example, you call the get functions from within theMainWindow
.
How it's done and how you pass data to your dialog class, I've already explained in my post here.And if you don't want the user to click any buttons, what's the point using a
QDialog
class, which returns a "state" whether the dialog wasrejected
oraccepted
by the user?Ok, so a strategy change. Create a class to serve as a repository for shared data. Call it "repo" for repository. Keep the data private. Provide public get and put functions that dialogs can access. This class will not do any processing, just serve as a repository for shared data.
This sounds like a data "model". Therefore have a look at Qt's Model/View section and classes:
Ask yourself what do you really need/want... How your dialogs (or whatever you are using to display or modify your data) should look like and how you want to manage them.
What kind of data you have?
Consider using a proper data model + the right "view" class for displaying, when you are dealing with more complex data.So, please, if you don't have any questions regarding how to "Open a dialog from other than mainwindow" left, mark this topic as "solved" and create new topic(s) for your further questions.
Because I feel like this topic isn't going somewhere. You reply to suggestions dealing with your initial problem with new/other issues. -