PDA

View Full Version : Qt/Code Design Problem - calling object from another object.



johnnyturbo3
20th August 2010, 09:59
Hi,

I have a code design problem:

I have several classes
*MainWindow - holds 2 widgets, a QTableView Widget and a QTabWidget
*TabLayout - layout of the tab, comboboxes etc. Creates an instance of TabCode and connects its signals to it.
*VideoTab - contains the slots. Slots are called whenever a combobox is activated.
*SQLconnection - contains static functions to populate the combobox's options.


The program has two parts - a SQL table and a collection of tabbed options.
When a user selects an option from the tab's combobox, the SQL table's query needs to be changed to reflect the user's selection.

The GUI looks like this at the moment:
5089


What I need is to be able to communicate from the VideoTab object to the MainWindow object whenever the user selects a combobox/whenever a slot is activated. I've attached a diagram to illustrate my ideas:
5090



I've tried using a static method, but that would mean that I would have to also make QSQLQueryModel static in order to modify its setQuery() function. Here's the MainWindow code for reference:


#include <QtGui>
#include <QMessageBox>
#include <QString>
#include <QtSQL>
#include <QVector>
#include <QString>
#include <QSqlTableModel>
#include "MainWindow.h"
#include "VideoTab.h"
using namespace std;



MainWindow::MainWindow(){
this->db = QSqlDatabase::addDatabase("QSQLITE", "myConnection");
db.setDatabaseName("myDataBase.sqlite");
db.open();
createDisplay();

}




void MainWindow::createDisplay(){
createModelView();
QTableView *view = new QTableView();
view->setModel(model);
view->show();

createTabView();
QHBoxLayout *mainLayout = new QHBoxLayout();
mainLayout->addWidget(view);
mainLayout->addWidget(tabWidget);
this->setLayout(mainLayout);


setWindowTitle(tr("Menus"));
setMinimumSize(160, 160);
resize(1000, 400);

}





void MainWindow::createModelView(){
this->model = new QSqlQueryModel();
model->setHeaderData(0, Qt::Horizontal, tr(""));
model->setHeaderData(1, Qt::Horizontal, tr(""));
model->setQuery("Select * from video", db);
}




void MainWindow::createTabView(){
videoTab = new VideoTab;
tabWidget = new QTabWidget;
tabWidget->addTab((videoTab), tr("Video"));
//tabWidget->addTab(audioTab = new AudioTab, tr("Audio"));
//tabWidget->addTab(transportTab = new TransportStreamTab, tr("Transport Stream"));
}

I hope I've clear stated my problem. I look forward to any comments or suggestion you peeps my have.

Thanks!

Lykurg
20th August 2010, 10:12
It all looks like you want have a look at the signal and slot mechanism of Qt: http://doc.trolltech.com/latest/signalsandslots.html

Lykurg
20th August 2010, 10:17
... as a pseudo code:
// in VideoTab
Q_EMIT mySignalWhichShouldDoSomethingInMainWindow();
// in TabLayout you do: (assuming you have a backpointer to your MainWindow:
connect(videoTab, SIGNAL(mySignalWhichShouldDoSomethingInMainWindow( )),
backPointerToMainWindow, SLOT(doSomething());
// and in main window:
void MainWindow::doSomething()
{
// something in VideoTab has changed.
}

johnnyturbo3
20th August 2010, 10:34
I've tried creating a signal/slots. Something like:


connect(vTypeCombo, SIGNAL(activated(const QString)), this->parent(), SLOT(videoUpdate()));
or

connect(vTypeCombo, SIGNAL(activated(const QString)), this->parent(), SLOT(MainWindow::videoUpdate()));
where videoUpdate() is a public slot. However, I get no response from the slot (nor error message).

With a backPointerToMainWindow, do you mean:



MainWindow *backPointerToMainWindow = this; //memory address of MainWindow object? Correct?
or
MainWindow *backPointerToMainWindow = *this; //'value' of memory address, i.e. MainWindow object? Correct?
And then pass this pointer to the VideoTab object's constructor?

Thanks for your help. I'm still learning C++ and all of it's pointer/references related material.

Lykurg
20th August 2010, 13:07
the parent() function is useless since you only get a pointer to an QObject not to your actual class, so you have to cast it. Or simply do something like
//in class A
B* b = new B(this);
// in class B
B::B(A* a)
{
C* c = new C;
connect(c, SIGNAL(/*...*/), a, SLOT(/*...*/));
// or
A* a = qobject_cast<A*>(this->parent());
//...
}