PDA

View Full Version : General: Structure of a Qt mainwindow program



kaizimir
4th September 2009, 13:10
Hello everybody,

I wonder how to layout the classes for a Qt program. I am using the designer for generating the *.ui and the ui_mainwindow.h.
Main instantiates an mainwindow object from a MainWindow class, which calls the setupUi method of the ui_mainwindow.h in its constructor. So far it is standard, I guess.

I thought, it is a good idea, to have several GUI related helper classes that can execute some special tasks, like plotting different types of graphs or adjust the controll widgets to the current user-operations... Is that recommended or should I do all that stuff in the MainWindow class?

If I use these helper classes, they need to have access to the widget objects instantiated in the setupUi method. How can I do this?
At the moment I am justing handing over a pointer of the widget to the helper class so I can manipulate that widget in the helper class.
But I can imagine that this can become very tedious if the program is growing more complex.
So, how can I, and this is the most important question to me, inherit the MainWindow or ui_MainWindow classes with the helper classes, so that the widgets instantiated in setupUi are accessible in the helper classes?

I am happy about every hint :)

greetz, kai

udit
4th September 2009, 14:11
I think you mean to say how do you access the widgets in the Designer you created are not getting accessible or dont know how to access

i can tell you some simple example to access them
especially the slot of the widgets

if you have created a line edit , then refer to the coding of ui_mainwindow.h, there you will find the slots you have created or you can add your own

to access the slot like that of textchanged of line edit you created , you may refer it by on_lineedit_textchanged
and connect it by the line
connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(on_lineEdit_textChanged()));
refer the ebooks for better clarification
hope that helps !!!!!!!!!

kaizimir
6th September 2009, 18:44
For me it is a little difficult to explain the coding in human language, therefore my question is maybe not very clear.

What I want to know is, how to inherit the ui_mainwindow or mainwindow class so that I have access to all the widget objects instantiated in the setupUi method?

greetz, kai

victor.fernandez
7th September 2009, 10:05
There are two ways. You may subclass the Ui::MainWindow class or have it as a class member. I personally prefer the first way but it's mostly a matter of taste.

The first one (the multiple inheritance approach (http://doc.trolltech.com/4.4/designer-using-a-component.html#the-multiple-inheritance-approach)):

mainwindow.h

#include "ui_mainwindow.h"

class MainWindow : public QMainWindow, private Ui::MainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);

protected slots:
void sayHello();
};

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUi(this);

connect(m_myButton, SIGNAL(clicked()),
this, SLOT(sayHello()));
}

void MainWindow::sayHello()
{
m_myLineEdit->setText(tr("Hello world"));
}

For the second way (the single inheritance approach (http://doc.trolltech.com/4.4/designer-using-a-component.html#the-single-inheritance-approach)):

mainwindow.h

#include "ui_mainwindow.h"

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
MainWindow(QWidget *parent = 0);

protected slots:
void sayHello();

private:
Ui::MainWindow ui;
};

mainwindow.cpp

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);

connect(ui.m_myButton, SIGNAL(clicked()),
this, SLOT(sayHello()));
}

void MainWindow::sayHello()
{
ui.myLineEdit->setText(tr("Hello world"));
}

More details (http://doc.trolltech.com/4.4/designer-using-a-component.html).

kaizimir
7th September 2009, 12:02
Thx a lot for the post. I didn't know that there are two ways of doing it. That clarified a little about my question.

I used the first way you described, to subclass the Ui::MainWindow. So far, so good.

Now, I'd like to have a third class, let's say, MainWindowPlot, which is only concerned with the plotting job. Therefore it needs full access to the widgets instantiated in the setupUi method. How can I subclass from the Ui::MainWindow to accomplish this? And, is doing it like this recommended?

greetz, kai

victor.fernandez
7th September 2009, 17:57
If you need to have full access to the widgets, it might be easier to use the single inheritance approach (the second method). You could create Ui::MainWindow in the heap instead of in the stack and add a method in your class that returns a pointer to it.

However, I don't recommend doing so. If you just want to read/write the values of the widgets, it would be safer that your main window provides methods to access the values of the widgets instead of letting other classes access the widgets directly. You might provide a value() and setValue() class where you specify the name of the field. For instance:



QString MainWindow::value(const QString& fieldName)
{
if(fieldName == "Name")
return m_name->value();
else if(fieldName == "Email")
return m_email->value();
...
}

Even better, you may use a QHash<QString, QWidget*> to store the relevant widgets where you can find them by field name:


class MainWindow : public QMainWindow, private Ui::MainWindow
{

...

private:
QHash<QString, QWidget*> m_fields;
};


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUi(this);

m_fields.insert("Name", m_name);
m_fields.insert("Email", m_email);
}


QString MainWindow::value(const QString& fieldName)
{
QWidget *widget = m_fields.value(fieldName);
if(!widget)
return QString();

if(widget->metaObject()->className() == "QLineEdit") {
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(widget);
return lineEdit->text();
}
...
}

kaizimir
7th September 2009, 18:33
Great, thanks for that explanation and the ideas! This is exactly what I was looking for :D

I don't understand the code in complete, but with a little time (next weekend) I can figure it out.