Solved How to access methods of MainWindow from Dialog Form (Subclassing I guess!)
-
Hello, please I need help.
I have my MainWindow and my Dialog, both created with QDesigner.
My MainWindow possesses a QTextEdit entitled 'textEdit' and my Dialog has a QPushButton named 'clickOk'
My concern is : I want when I click on that QPushButton of my Dialog that he clears everything I wrote in the textEdit using 'clear()' method of QTextEdit.
Of course I use signal and slot but it's not working, I mean when I click on QPushButton nothing occurs in the textEdit of my MainWindow.
by the way, I use modeless to show my Dialog using 'show()' method and it's works perfectly:
this is the code
QDialog *dlg = new QDialog(this); dlg->show();
I don't want to use modal with '.exec()' function as I want the user to still use both at the same time.
Below's my implementation for everything (the two Forms) :
IMPLEMENTATION
MainWindow.h
public slots: void clearText();
MainWindow.cpp
void MainWindow::clearText() { ui->textEdit->clear(); //QMessageBox::information (this, "TITLE", "WORKING = OK"); }
Dialog.h
Private or Pulic slots: // even if I put it in public or private, it still doesn't work void clearClick();
Dialog.cpp
//in the constructor connect(ui->clickOk, SIGNAL(clicked()), this, SLOT(clearClick()));
void QDialog::clearClick() { // I tried both methods below but nothing seems to happen // First Method QMainWindow dlg; dlg.clearText(); // Second Method QMainWindow *dlg = new QMainWindow(); dlg->cleanText(); }
PS : I tried to test if my ' void MainWindow::clearText() ' of the MainWindow works by inserting a QMessageBox in it,
when I click on QPushButton of the QDialog, and of course it really goes through that function, because the QMessageBox appears when I execute the project... but 'ui->textEdit->clear();' doesn't work.
Thanks for your help in advance
-
Hi
The code is a bit confusing.
You do
QMainWindow dlg;
dlg.clearText();
which is a new copy of mainwindow so it wont contain the text you except.I made a small example of how you can do it
https://www.dropbox.com/s/wqc2muwxkkjd5s5/cleartoclick.zip?dl=0In words its the following:
In Dialog we make new public signal ClearClicked
We connect (in dialog) the button's "clicked" signal to our new signal ClearClicked
(since we can't connect directly to button from mainwindow)
Then in mainwindow we connect this new signal ClearClicked to a function
in mainwindow (ClearText ) that clears the text..
-
My second way to do that was this below : "I forgot to paste the code in my first post"
// Second Method QMainWindow *dlg = new QMainWindow(); dlg->cleanText();
Thanks for your prompt reply.
I'm taking a look at the project your gave me, and I'll get back to you for more question. -
As a rule of thumb, I recommend you to make connections from the parent widget, who is aware of it's children since children are often created from parent widget. This is what mrjj coded:
- the main window creates the dialog;
- the dialog can emit a signal when its button is pushed;
- the main window connects this signal to a custom slot;
- the slot does the clear.
You were trying the reverse way.
Moreover, creating connections from the parent widget enables you to make two children communicate between them, without having to know each other.
-
Sorry for the delay, I was writing my CCNP Exam.
@"mrjj"
you said “(since we can't connect directly to button from mainwindow)”So if i understand very well, you mean, in all my Qt applications that I will develop that possess more than one Form, objects of the UI like Label, Button, TextBox... in the Main Window ARE NOT DIRECTLY accessible from an another dialog,
so I must ALWAYS create a signal to do so.I've also read something like that in two Qt books I have but I needed a very clear clarification like that.
You know what, I really like your explanation on the post as well as in the source code your sent me,
it’s very very clear to newbie.I hope you’ll be (you're) a very good teacher.
and I like the way you give source-code as an example instead of saying a lot of theories like some people else in other Qt Forum.
So if i understand the signal according to your project,
a signal is a empty function??because I did not see any implementation of the signal “ClearClicked” in mydialog.cpp, you just defined/declared it in mydialog.h.
so basically, a signal is like a empty method?Thanks very much for you help.
Thanks as well to ValentinMichelet for your explanation.
PS : Please I know that the matter is solved but you can keep posting comments and explanations if you have, I'll read and reply as well.
Have a wonderful week-end!
-
@freesix
Hi welcome back
When you design a form or dialog. The objects you insert in the editor
are put it a special UI object.
For mainwindow its
#include "ui_mainwindow.h"
This is auto created by the editor and is basically just a normal c++ object containing
all the widgets you put in the UI form.
class Ui_MainWindow {
public:
QPushButton *btRec;
QPushButton *btSend;
QMenuBar *menuBar;
...
In the mainwindow class is then a variable of that Ui_MainWindow type
private:
Ui::MainWindow *ui;This allows us to say ui->btSend (or any other widget) in all methods of mainwindow.
However, since ui is private, no other class can access the widgets directly.
(like btSend).
This is the reason I say we cannot direct access another forms or dialogs ui's widgets.
It is possible to allow access by make access functions in the owning class
like
QPushButton * MainWindow::GiveMeSendButton() { return ui->btSend; }
But we don't like to do it as it makes rest of program aware of we have such button.
(and if we then make it a spinbutton, we need to change other forms too as they knew exact type)
so we use the signal trick so rest of program don't know the exact widget. (called encapsulation)a signal is a empty function??
Yes. it is just a normal function but we never define a body for it.
Only the name and parameters are important. (the signature of the signal)You will not always use the signal approach. You can also make concrete access function for others to use.
Say you have a dialog where user inputs a Delay. (it stays open)
Then if say mainwindow wants to read it at some point.
You define a GetDelay () function in the dialog that mainwin just uses.
this is instead of allowing mainwin to do like
Dialog->ui->Edit->getText() , getting the value directly off the widget.
Instead we define methods to let others get the data without knowing how we really do it (inside)
Hope it makes sense :)Super nice weekend to you too
-
Thanks, I do appreciate your explanation.
-
Hello,
in the source code, there is a public signal (according to you)
but I don't see anything that put that 'signal' public or private.
Can you explain it for me please???
-
Hi
well it lists it as a slot
signals:
void ClearClicked();its listed in the public section.
class MyDialog : public QDialog{
public:
signals:
void ClearClicked();Meaning it can be seens from outside class.
Public also in the sense that it is used to re-signal
a signal from inside the dialog as mainwindow
dont have directly access to the UI widgets to set it directly.
connect(Dia, SIGNAL(ClearClicked()), this , SLOT(clearText())); -
Okay thanks