Access the UI, from multiple windows.
-
@Loc888
Hi
Im not sure what part is causing your problems.
Maybe we talk about different things.Yes, you can make a reference to a window.
or give a pointer / ref to a window to another window.Like create settings_win in main.cpp
give it to mainwindow.
Mainwindow create a new Window and give settings_win to that also.@mrjj Yes, and that's the problem. Maybe i name this topic title a little bit bad, but i dont have any problem with access, because i can access them all.
The problem is, when i pass the window with that function, it's seems like another copy, not reference, so when i change something, nothing happens because it change the copy variables, and i dont know why it happend.
If i pass ther the window object, UI stuff should be ther??
-
@mrjj Yes, and that's the problem. Maybe i name this topic title a little bit bad, but i dont have any problem with access, because i can access them all.
The problem is, when i pass the window with that function, it's seems like another copy, not reference, so when i change something, nothing happens because it change the copy variables, and i dont know why it happend.
If i pass ther the window object, UI stuff should be ther??
@Loc888 Let's clean up your code.
// You need to declare S_Window_Temp as reference to pointer, else you cannot change it inside GetWindowData! void MainWindow :: GetWindowData(Settings_Window* &S_Window_Temp) //<< Here i send Object from Settings_Window created in Window1 { S_Window_Temp = &S_Window; // So i expect C (Object form Window1) should be equal to S_Window (Object form MainWindow ), but it's not. }
Actually you should simply return the pointer from GetWindowData as your current API design is bad (it isn't a good idea to change method parameters from inside the method):
Settings_Window* void MainWindow :: GetWindowData() { return &S_Window; }
-
@Loc888 Let's clean up your code.
// You need to declare S_Window_Temp as reference to pointer, else you cannot change it inside GetWindowData! void MainWindow :: GetWindowData(Settings_Window* &S_Window_Temp) //<< Here i send Object from Settings_Window created in Window1 { S_Window_Temp = &S_Window; // So i expect C (Object form Window1) should be equal to S_Window (Object form MainWindow ), but it's not. }
Actually you should simply return the pointer from GetWindowData as your current API design is bad (it isn't a good idea to change method parameters from inside the method):
Settings_Window* void MainWindow :: GetWindowData() { return &S_Window; }
@jsulm If i just copy and paste, your code, it gives me an error.
The best solution I found is just create the definition of the object in mainwindow.cpp under include, i test it with my own class, and it works exacly how i wanted it.
Unfortunately when i do the same thing with the Window, it crash the application and gives a message:
"QWidget: Must construct a QApplication before a QWidget"
Any way to fix it?
-
Hi,
The usual fix to this one is: don't create static QWidget based objects.
-
If you have anything that looks like
static MyClass thingy
where MyClass is derived from QWidget, then remove it. -
@Loc888
Hi
You cannot have global Widgets as they are NOT
allow to be constructed before QApplication in main.
They must be pointers and you can first new them After application is created.@mrjj I tried by reference, and this happend:
Error: 'QWidget& QWidget::operator=(const QWidget&)' is private
Class &operator=(const Class &) Q_DECL_EQ_DELETE;
^mingw48_32\include\QtWidgets\qwidget.h:728: in expansion of macro 'Q_DISABLE_COPY'
Q_DISABLE_COPY(QWidget)
^It happend in this line Class &operator=(const Class &) Q_DECL_EQ_DELETE;
I try later with pointers, and will see what happend.
-
Now i tried with pointers, error :
error: invalid operands of types 'Settings_Window*' and 'Settings_Window*' to binary 'operator*'
A* &Settings_Widget;
^void MainWindow::Get_Window_Data(Settings_Window* A)
{A* &Settings_Widget;
}
What i did wrong?
-
Now i tried with pointers, error :
error: invalid operands of types 'Settings_Window*' and 'Settings_Window*' to binary 'operator*'
A* &Settings_Widget;
^void MainWindow::Get_Window_Data(Settings_Window* A)
{A* &Settings_Widget;
}
What i did wrong?
-
@Loc888
Hi
Why not just
Settings_Window* MainWindow::Get_Window_Data()
{
return Settings_Widget; // Settings_Widget is * (pointer) ?
}It run at least, but is not working. If i check something, then press the button with this code, nothing happened. Probably is another copy.
I am tired, tomorrow i try something else.Is this the way how i should use it?
MainWindow B; if(B.Get_Window_Data()->ui->Checker_Box_01->isChecked()) { //Do something }
-
Hi
Yes but im old school and always check pointers
so i would doMainWindow B; // this should not be a second instance but the one you (might) create in main.cpp
Settings_Window * win=B.Get_Window_Data();
if (!win) { qDebug() << "NULL ptr from Get_Window_Data"; return; } if(win->ui->Checker_Box_01->isChecked()) { //Do something } if(win->ui->Checker_Box_XX->isChecked()) { //Do something }
However, the UI variable is private so unless the using class is friend, its not allowed.
So you make make UI public ( bad design )
or provide access functions for the widgets. -
It run at least, but is not working. If i check something, then press the button with this code, nothing happened. Probably is another copy.
I am tired, tomorrow i try something else.Is this the way how i should use it?
MainWindow B; if(B.Get_Window_Data()->ui->Checker_Box_01->isChecked()) { //Do something }
@Loc888 said in Access the UI, from multiple windows.:
B.Get_Window_Data()->ui->Checker_Box_01->isChecked()
From software design point of view this is so bad!
You should not expose internal details of your MainWindow like that.
Add public methods to MainWindow which return needed invormation without exposing internal implementation details.
Example:class MainWindow... { public: bool isSomethingActivated() { return ui->Checker_Box_01->isChecked(); } } MainWindow B; if(B.isSomethingActivated()) { //Do something }
Now, the user of MainWindow does not have to know anything about how the MainWindow is designed (what UI elements it has for example) - it just calls a public interface method to get the information. Usn't this much nicer? One more advantage of this approach: if you later change your MainWindow UI the caller of the MainWindow will not be affected.
Example:class MainWindow... { public: bool isSomethingActivated() { // You decided that the condition should be different return ui->Checker_Box_01->isChecked() && ui->Checker_Box_02->isChecked(); } } // No need to change the caller of MainWindow MainWindow B; if(B.isSomethingActivated()) { //Do something }
-
@Loc888 said in Access the UI, from multiple windows.:
B.Get_Window_Data()->ui->Checker_Box_01->isChecked()
From software design point of view this is so bad!
You should not expose internal details of your MainWindow like that.
Add public methods to MainWindow which return needed invormation without exposing internal implementation details.
Example:class MainWindow... { public: bool isSomethingActivated() { return ui->Checker_Box_01->isChecked(); } } MainWindow B; if(B.isSomethingActivated()) { //Do something }
Now, the user of MainWindow does not have to know anything about how the MainWindow is designed (what UI elements it has for example) - it just calls a public interface method to get the information. Usn't this much nicer? One more advantage of this approach: if you later change your MainWindow UI the caller of the MainWindow will not be affected.
Example:class MainWindow... { public: bool isSomethingActivated() { // You decided that the condition should be different return ui->Checker_Box_01->isChecked() && ui->Checker_Box_02->isChecked(); } } // No need to change the caller of MainWindow MainWindow B; if(B.isSomethingActivated()) { //Do something }
-
@jsulm
And we come full circle \o/
I told OP that 4 days ago, but he seems unwilling to
create access functions :)
Maybe seeing your good example, OP will feel the joy of good design
and do it the right way. -
It makes me a little bit mad, why everything need's to be complicated.
So, in main window can i use something like that:B.Get_Window_Data()->ui->Checker_Box_01->isChecked()
But in other window, i need to do it in other way?
@Loc888 You should no access internal implementation details of one window (class) from another. It is not related to Qt, this are simply software design basics...
And what is complicated about it? Is my example really complicated? What you're trying to do is much more complicated and error prone. Why do you want to know in window A how window B is constructed? Why not simply define simple APIs to communicate between windows? To be honest code like what you're trying to write would not pass code reviews in the company where I'm working. -
@jsulm
And we come full circle \o/
I told OP that 4 days ago, but he seems unwilling to
create access functions :)
Maybe seeing your good example, OP will feel the joy of good design
and do it the right way.@mrjj Listen, i show you my code, cuz i am getting a little bit crazy, i can't create it in main.cpp, becasuse then how can i show it?
In MainWindow.h i have
Settings_Window* Get_Window_Data(); Settings_Window* Settings_Widget = new Settings_Window;
MainWindow.cpp
Settings_Window* MainWindow::Get_Window_Data() { return Settings_Widget; }
Window1
MainWindow B; Settings_Window S; if(B.Get_Window_Data()->ui->Checker_01->isChecked()) { }
-
@Loc888 You should no access internal implementation details of one window (class) from another. It is not related to Qt, this are simply software design basics...
And what is complicated about it? Is my example really complicated? What you're trying to do is much more complicated and error prone. Why do you want to know in window A how window B is constructed? Why not simply define simple APIs to communicate between windows? To be honest code like what you're trying to write would not pass code reviews in the company where I'm working. -
@jsulm
And we come full circle \o/
I told OP that 4 days ago, but he seems unwilling to
create access functions :)
Maybe seeing your good example, OP will feel the joy of good design
and do it the right way.@mrjj This method is not working
Settings_Window* MainWindow::Get_Window_Data() { return Settings_Widget; }
If i press the checkerbox, it should be setted to true
void Settings_Window::on_CheckerBox_clicked() { B->Get_Window_Data()->ui->CheckerBox->setChecked(true); }
Then when i go to window one, and press the button
void Window1::on_Button001_clicked() { MainWindow* B = new MainWindow; if(B->Get_Window_Data()->ui->Auto_Reset_Data_Timer->isChecked()) { //do something } }
I don't understand all your methods, so if anyone can, please correct this stuff, cuz i have enough.