March 7, 2011

pag-r pag-r
Lab Rat
10 posts

accessing from one form to another

 

Hi.
I’m new in Qt and I’ve stuck with a problem. I have QDialog to edit sql record, and MainWindow with viewTable. And all i want to do is possibilty to “refresh” viewTable in MainWindow when I click save button on edit dialog. Is there any way to do it without inheritance? I’ve searched forum and google as well, I’ve tried signals and slots but I’m far too new in Qt to do it properly.
Regards.

15 replies

March 7, 2011

Andre Andre
Robot Herder
6394 posts

Signals and slots are the right track.
What you are after is communication between two objects. It doesn’t really matter if the objects are forms or something else. What you might do, is equip your main window with a slot (I propose to call it refresh()), and give your dialog a signal called triggerRefresh(). Then, when you create your dialog from your main window, you connect the signal to the slot you just defined. Next, you need to make sure you actually emit the signal from the dialog at the appropriate time.

However, I am wondering, if you need all of this. I assume the dialog will only need to be visible while editing a record, and after editing (on pressing Save) the dialog will be closed and only then the main window will need to update? In that case, you can just make the dialog modal and trigger the update based on the result of your dialog (accepted or rejected; you only refresh on accepted (Save) of course).

Yet another way of dealing with this, may be to make use of the model/view framework. Since you display a table, you have a model that holds your data, I’d think. You currently pass the dialog you use to edit the data the actual data to edit, I assume. Am I right? How about instead of passing the data, you pass the relevant QModelIndex(-es)? That way, you can simply have the edit dialog call setData() on the model when you click the Save button, and the data will be stored in the underlying model directly and automatically updated in your main window. Note that this way also uses signals and slots, but those signals and slots are already part of the model/view framework.

March 7, 2011

pag-r pag-r
Lab Rat
10 posts

Thank You for reply, Andre. Dialog is set to modal and I’m trying to do it exactly in way You’ve wrote in second paragraph. However I’m not sure how to do it properly, anyway I will try to implement it.

March 7, 2011

Andre Andre
Robot Herder
6394 posts

Well, you should recognize that when the dialog’s exec() call returns, you still have access to a variable that represents that dialog. That gives you the opportunity to call methods on the dialog: that it is closed (no longer visible to the user), does not mean the object is destroyed! So, just give your dialog some methods to access the values you need, and call on those methods from your main window after the dialog has returned an accepted value.

March 7, 2011

pag-r pag-r
Lab Rat
10 posts

I assume that the connect should be in my QDialog constructor?

  1. connect(ui->pushButtonSave, SIGNAL(clicked()),QObject MainWindow, SLOT(MainWindow::refresh()));

And I don’t have any idea how to declare MainWindow connection. QObject MainWindow doesn’t work…

March 7, 2011

Andre Andre
Robot Herder
6394 posts

If you want a signal-slot connection (I thought that you understood that you don’t need one), then you make such a connection at the place where you have references to both the involved objects. The most logical place in this case would be the place in your mainWindow code where you create the dialog. So, not in the constructor of the dialog. Something like this:

  1. EditDialog* editDialog = new EditDialog(this);
  2. //set your values
  3. connect(editDialog, SIGNAL(triggerRefresh()), this, SLOT(refresh()));
  4. editDialog.exec();
  5. //...

To make your dialog actually emit the signal, you may do something like this in the constructor of your dialog:

  1. connect(ui->pushButtonSave, SIGNAL(clicked()), this, SIGNAL(triggerRefresh()));

Note that it seems that you did not use QDialog as the base of your dialog. Perhaps you should re-evaluate that choice. QDialog gives you the option to use standard buttons, including a save button, that have the appropriate roles pre-defined. The nice thing is, is that they will order themselves in the order that is defined by the platform your application runs on, so the user is never suprised by what button will cancel and what button will accept.

March 7, 2011

pag-r pag-r
Lab Rat
10 posts

I think I don’t really understand the idea of slots/signals and triggers too :/, so I better learn more basics:). My last experience with GUI was C++ Builder, and Qt is something completly new for me. in Builde what i have to do was include header file of second form and it was just all. Thanks for reply.

March 7, 2011

pag-r pag-r
Lab Rat
10 posts

I can’t do it. Could somebody show me an example of accessing one form from another?
My test code
from mainwindow.h

  1. public slots:
  2.     void test();
  3.     void trigger();
  4.  
  5.   private slots:
  6.     void on_pushButtonMainWindow_clicked();

mainwindow.cpp
  1. void MainWindow::on_pushButtonMainWindow_clicked()
  2. {
  3.   Dialog dialog(this);
  4.   connect(this, SIGNAL(trigger()), &dialog, SLOT(test()));
  5.   dialog.exec();
  6. }
  7.  
  8. void MainWindow::test()
  9. {
  10.   ui->lineEdit->setText("efgh");
  11. }
  12. void MainWindow::trigger()
  13. {
  14.   ui->lineEdit->setText("this is a test");
  15. }

from dialog.cpp
  1.     connect(ui->pushButtonDialog, SIGNAL(clicked()), this, SLOT(MainWindow::trigger()));

And it gives me:
  1. Object::connect: No such slot Dialog::MainWindow::trigger() in ..\slots\dialog.cpp:9
  2. Object::connect:  (sender name:   'pushButtonDialog')
  3. Object::connect:  (receiver name: 'Dialog')
  4. Object::connect: No such signal MainWindow::trigger() in ..\slots\mainwindow.cpp:20
  5. Object::connect:  (sender name:   'MainWindow')
  6. Object::connect:  (receiver name: 'Dialog')

Sorry for double post

March 7, 2011

Volker Volker
Ant Farmer
5428 posts

Signals are sent from the objects that define them. Your main window has no signal trigger – that’s what the debug console tells you literally :-)

In your case, you probably want to connect a signal of a button or an action to the slot.

If you define your own signal triggered, it does not need an implementation in the cpp file (actually you must not provide any!). And if you have that your signal must be emit somewhere to have the connection be called in the end.

Did you read the Signals & Slots [doc.qt.nokia.com] docs already?

March 7, 2011

pag-r pag-r
Lab Rat
10 posts

I’ve briefly read this doc and C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield too (about signals and slots).
More, in project I’m actually working with, I have 2implementations of signals & slots, and they are working fine. But they both signals and slots in mainwindow area.

  1.       connect(ui->tableViewHouses, SIGNAL(clicked(const QModelIndex&)), this, SLOT(clickedRow(const QModelIndex&)));
  2.       connect(ui->tableViewInhabitants, SIGNAL(doubleClicked(const QModelIndex&)),
  3.               this, SLOT(doubleClickedRow(const QModelIndex&)));

I have a problem to connecting from main to dialog. I know that problem is my lack of knowledge, but i have no idea howto do it between different windows

March 7, 2011

Andre Andre
Robot Herder
6394 posts

Does your edit dialog have a signal defined called trigger (that is, does it have a line in the header file that looks like this)?

  1. signals:
  2.     void trigger();

On top of that, do you have this line in the header of that dialog?

  1. Q_OBJECT // this line is usually the first line inside the actual class definition

Your error message suggests that you don’t.

March 7, 2011

Volker Volker
Ant Farmer
5428 posts

Define the signal in one form, emit when you have something to tell to the other form.

Connect in the other form. Or connect in some managing code – it depends.

Other possibility is to give the form a pointer to the other form and call a method directly.

Or do it like Andre suggested:
Call exec() on a QDialog [doc.qt.nokia.com] subclass and get the data from a method of this dialog and put it into the widgets of the main form, if the exec returns with Accepted.

I personally would go with the last approach.

March 7, 2011

pag-r pag-r
Lab Rat
10 posts

Andre wrote:
Does your edit dialog have a signal defined called trigger (that is, does it have a line in the header file that looks like this)?
  1. signals:
  2.     void trigger();

On top of that, do you have this line in the header of that dialog?

  1. Q_OBJECT // this line is usually the first line inside the actual class definition

Your error message suggests that you don’t.


Yes, I haven’t get signal, I’ve added trigger now, but still it doesn’t work properly.
pastebin [pastebin.com]

//edit
Its to much for me. Im quiting with this. Thanks for Your replies and Your time. Maybe some other time I’ll try to understand slots and signals between forms.

March 7, 2011

Volker Volker
Ant Farmer
5428 posts

What you do is: Have the main window emit a signal that the dialog reacts on. You most probably want it the other way round!

Good luck with your projects so far. If you only read the docs briefly you’ll be stuck in similar situations here and then in the future again… be warned!

March 8, 2011

pag-r pag-r
Lab Rat
10 posts

It works:) Thank You both for help. I’ve do it nor in signals&slots but in the way which Andre suggested with dialog set on Accepted

  1. void MainWindow::on_pushButton_clicked()
  2. {
  3.     Dialog *dlg = new Dialog(this);
  4.     if(dlg->exec() == QDialog::Accepted) ui->lineEdit->setText("Accepted");
  5. }

This works perfectly for me, altough i know that i will have to learn slots&signals in future.
Thanks again for Your suggestions.
Best regards.

August 19, 2012

sandy.pareek sandy.pareek
Lab Rat
16 posts

nicely explained, here…

 Signature 

“my code, my life”

 
  ‹‹ [Solved] Qt package versioning for Ubuntu      howto set a single item in stylesheet ››

You must log in to post a reply. Not a member yet? Register here!