PDA

View Full Version : Q_OBJECT, vtables and basic GUI control.



Diath
29th July 2010, 18:13
Hello QT Geeks!

I have to create GUI for my application and after re-search I've had to choose between wxWidgets and QT, and my choice was QT.
I've downloaded newest QT Version from http://qt.nokia.com (i.e. 4.6.3), MinGW 5.1.6 and Code::Blocks (Also latest version.) and I'm working on Windows XP Professional Service Pack 3.
I've configured my Code::Blocks using some wiki tutorial (Can't remember where did I find the link so can't post :/).

Basically I need 2 "windows" in 2 classes:
a) Login Window with 2 static texts, 2 text boxes and 3 push buttons.
b) Client window with few tabs, buttons and such.

Here's my code:

main.cpp:


#include <QApplication>
#include "LoginInterface.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

LoginInterface li;
li.show();

return app.exec();
}



LoginInterface.cpp:


#include <QLabel>

#include "LoginInterface.h"

LoginInterface::LoginInterface()
{
QLabel *NameDialog = new QLabel(tr("Name:"));
NameDialog->show();
}



LoginInterface.h:


#ifndef LOGININTERFACE_H
#define LOGININTERFACE_H

#include <QMainWindow>

class LoginInterface : public QMainWindow
{
Q_OBJECT
public:
LoginInterface();
};

#endif



As you can see in LoginInterface header file, there's Q_OBJECT variable, but with this variable I'm getting following errors:


obj\LoginInterface.o:LoginInterface.cpp:(.text+0x6 6): undefined reference to `LoginInterface::staticMetaObject'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x7 1): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x7 8): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x1 f8): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x1 ff): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x2 13): undefined reference to `LoginInterface::staticMetaObject'


But when I remove that (Yea I know, ugly cheat. :p), everything compiles fine, but GUI comes with separated windows, like on this screen:
http://img822.imageshack.us/img822/1023/65155635.png

Is there any way to fix Q_OBJECT thing and fix windows, so new controls will be CHILDS, not separated windows?

Also I've tried other ready code and C::B threw me error about 'Undefined QThread' or something, do I miss some parts of QT or?

Cheers, Diath.
PS: I hope you'll understand my english, it's kinda bad but i tried to write as proper as I can.

tbscope
29th July 2010, 18:29
There are a couple of things not completely correct.

The following code is ok:

#include <QApplication>
#include "LoginInterface.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

LoginInterface li;
li.show();

return app.exec();
}

The LoginInterface class isn't.
Try this:

#ifndef LOGININTERFACE_H
#define LOGININTERFACE_H

#include <QDialog>

class LoginInterface : public QDialog
{
Q_OBJECT

public:
LoginInterface(QWidget *parent = 0, Qt::WindowFlags flags = 0 );
};

#endif

And for the implementation try this:


#include <QLabel>
#include <QHBoxLayout>

#include "LoginInterface.h"

LoginInterface::LoginInterface(QWidget *parent = 0, Qt::WindowFlags flags = 0) :
QDialog(parent, flags)
{
QHBoxLayout *labelLayout = new QHBoxLayout;

QLabel *inputLabel = new QLabel(tr("Name:"));
QLineEdit *inputText = new QLineEdit;

labelLayout->addWidget(inputLabel);
labelLayout->addWidget(inputText);

setLayout(labelLayout);
}

If you create a widget within the code of another widget, and you don't set the parent of the new widget and then you call show(), you do show this new widget in a new window.

Use layouts. You don't have to explicitly set parents for child widgets as the layout reparents them and setLayout will make the parent widget take control of it.

Edit: and try to clean your project and rebuild it completely.

Zlatomir
29th July 2010, 18:29
This is where you need to pass the parent pointer (in your case the "this" pointer):


QLabel *NameDialog = new QLabel(tr("Name:"), this);

LE: to late, and incomplete :o

Diath
29th July 2010, 18:42
Thank you both guys for fast answers.

@tbscope:
I did try your code, and did as you wrote in your edit, but C::B threw me new errors:

C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.h:14:7: warning: no newline at end of file
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:6: error: default argument given for parameter 1 of `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.h:11: error: after previous specification in `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:6: error: default argument given for parameter 2 of `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.h:11: error: after previous specification in `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp: In constructor `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)':
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:12: error: `QLineEdit' was not declared in this scope
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:12: error: `inputText' was not declared in this scope
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:12: error: `QLineEdit' is not a type
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:12: warning: unused variable 'QLineEdit'

So I did add following code under #include <QLabel>:

#include <QLineEdit>

Now I'm getting only these errors (I assume they're about LoginInterface constructor.):

C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:7: error: default argument given for parameter 1 of `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.h:11: error: after previous specification in `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.cpp:7: error: default argument given for parameter 2 of `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'
C:\Documents and Settings\Kamil\Pulpit\The Bloody War\client_launcher\LoginInterface.h:11: error: after previous specification in `LoginInterface::LoginInterface(QWidget*, Qt::WindowFlags)'

tbscope
29th July 2010, 18:48
Yes, sorry, I posted it too quickly.
Indeed, add the qlineedit include
But also:


#include <QLabel>
#include <QHBoxLayout>

#include "LoginInterface.h"

LoginInterface::LoginInterface(QWidget *parent, Qt::WindowFlags flags) :
QDialog(parent, flags)
{
QHBoxLayout *labelLayout = new QHBoxLayout;

QLabel *inputLabel = new QLabel(tr("Name:"));
QLineEdit *inputText = new QLineEdit;

labelLayout->addWidget(inputLabel);
labelLayout->addWidget(inputText);

setLayout(labelLayout);
}

Remove the two = 0 as in the code above. It's not allowed to add default values in the implementation.

Diath
29th July 2010, 18:55
Well, I've removed = 0 in both .cpp and .h files, then I moved to main.cpp and my code looks now like this:

#include <QApplication>
#include "LoginInterface.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *MainWidget = new QWidget();
LoginInterface *li = new LoginInterface(MainWidget, Qt::Dialog);
li->show();

return app.exec();
}

But again, C::B throws me an errors:

obj\LoginInterface.o:LoginInterface.cpp:(.text+0x6 a): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x7 1): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0xb e): undefined reference to `LoginInterface::staticMetaObject'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x3 1a): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x3 21): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x3 6e): undefined reference to `LoginInterface::staticMetaObject'

I guess it's me who's doing something wrong, I really appreciate your help :p.

Zlatomir
29th July 2010, 18:56
Leave the =0 in header file

Diath
29th July 2010, 19:01
Still:

obj\LoginInterface.o:LoginInterface.cpp:(.text+0x6 a): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x7 1): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0xb e): undefined reference to `LoginInterface::staticMetaObject'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x3 1a): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x3 21): undefined reference to `vtable for LoginInterface'
obj\LoginInterface.o:LoginInterface.cpp:(.text+0x3 6e): undefined reference to `LoginInterface::staticMetaObject'

And yes, I did "clean and rebuild" project.

I have to leave for the moment, will take a look here later. I hope someone will help :p.

Zlatomir
29th July 2010, 19:15
Here you have the little project that works5016
LE: exact code that tbscope provided (incuding the two little corrections)

tbscope
29th July 2010, 19:30
Does your setup find the meta object compiler?

Diath
29th July 2010, 23:31
Here you have the little project that works5016
LE: exact code that tbscope provided (incuding the two little corrections)

Seems like I've installed QT wrong, still throws me an error.


Does your setup find the meta object compiler?

How do I check/fix? (Sorry for dumb questions.)

ChrisW67
30th July 2010, 04:46
How does Code::Blocks manage the steps needed to build a Qt program? Is Code::Blocks running your source through Qt moc (look for LoginInterface_moc.cpp) ? Is there a qmake PRO file?

If you have no pressing reason to stick with Code::Blocks then you should consider Qt Creator, which manages many Qt aspects for you.

Diath
30th July 2010, 10:55
How does Code::Blocks manage the steps needed to build a Qt program? Is Code::Blocks running your source through Qt moc (look for LoginInterface_moc.cpp) ? Is there a qmake PRO file?

If you have no pressing reason to stick with Code::Blocks then you should consider Qt Creator, which manages many Qt aspects for you.

There's no moc or pro file.

And I'm using C::B only to press damn F9 button, so I can switch to Qt Creator, but what then? Will I have to integrate MinGW or something with it? Is there any guide how to setup it properly?

Zlatomir
30th July 2010, 11:01
Qt SDK for Windows has everything ready to run, and the one for Linux need to have g++ and make installed on your system.

tbscope
30th July 2010, 11:01
If you download the Qt SDK, it includes everything. Just install it, open Qt Creator and build without problems.

Diath
30th July 2010, 12:18
http://img130.imageshack.us/img130/8393/32385197.png

Diath
30th July 2010, 15:12
Okay, I don't want to create new thread, so gonna post here.
I have button in LoginInterface class, and after passing click signal to that button I call following function:

void LoginInterface::Run()
{
// Totalny rozpierdol!
delete UserLabel;
delete UserInput;
delete MainLayout;

// Basic Tab
BasicWidget = new QWidget;
BasicLayout = new QGridLayout;

// // Basic Tab - Controls
UsernameLabel = new QLabel("User:");
UsernameEdit = new QLineEdit;
BasicWidget->setLayout(BasicLayout);

// // Basic Tab - Adding widgets
BasicLayout->addWidget(UsernameLabel);
BasicLayout->addWidget(UsernameEdit);

// Tabs
Tabs = new QTabWidget;
Tabs->addTab(BasicWidget, tr("Basic Info"));
Tabs->show();
}


But tabs comes in separated window, how do I pass parent? ;p

ChrisW67
31st July 2010, 07:56
Add the Tabs widget to a layout inside LoginInterface's central widget, or the layout of the window you want the widget to appear in, rather than "Tabs->show()". Exactly how you do that depends on exactly how things are arranged now, and what you want to happen.

Diath
31st July 2010, 14:23
Oh, lol. Thank you, solution:


MainLayout->addWidget(Tabs);


+ removing:


delete MainLayout;

Diath
31st July 2010, 15:41
Seems like bad solution, it doesn't fit window (It's like container inside other.), also I haven't "hook" with main window or something so I can't resize it. Any tips? :(

ChrisW67
1st August 2010, 00:56
If you want to replace the entire central widget of the QMainWindow with your tab widget then just call QMainWindow::setCentralWidget() (the existing central widget will be destroyed). If you intend to switch back and forth between several different central widgets then you should look at QStackedWidget.

If that is not what you want than you should post a small compilable example that shows what you are doing and then explain what you want it to do.

Diath
1st August 2010, 01:28
Well, I'm using QDialog, not QMainWindow, but yeah, it'll be easier to explain on code, here is it:

main.cpp:


#include <QApplication>
#include "LoginInterface.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

LoginInterface li;
li.show();

return app.exec();
}


LoginInterface.cpp:


#include "LoginInterface.h"

LoginInterface::LoginInterface(QWidget *parent, Qt::WindowFlags flags) :
QDialog(parent, flags)
{
MainLayout = new QGridLayout;

// GUI Controls
UserLabel = new QLabel(tr("User:"));
UserInput = new QLineEdit;

PasswordLabel = new QLabel(tr("Password:"));
PasswordInput = new QLineEdit;

LoginButton = new QPushButton(tr("Login"));
ExitButton = new QPushButton(tr("Exit"));

connect(LoginButton, SIGNAL(clicked()), this, SLOT(Login()));
connect(ExitButton, SIGNAL(clicked()), this, SLOT(Exit()));

// Adding Widgets
MainLayout->addWidget(UserLabel);
MainLayout->addWidget(UserInput);

MainLayout->addWidget(PasswordLabel);
MainLayout->addWidget(PasswordInput);

MainLayout->addWidget(LoginButton);
MainLayout->addWidget(ExitButton);

// Display
setLayout(MainLayout);
setWindowTitle("Login");
}

void LoginInterface::Run()
{
// Totalny rozpierdol!
delete UserLabel;
delete UserInput;

delete PasswordLabel;
delete PasswordInput;

delete LoginButton;
delete ExitButton;

// Title
data[1].clear();
data[1] = "Logged as " + data[0];
setWindowTitle(data[1]);
data[1].clear();

// Basic Tab
BasicWidget = new QWidget;
BasicLayout = new QGridLayout;

// // Basic Tab - Kontrolki
UsernameLabel = new QLabel("User:");
UsernameEdit = new QLineEdit(data[0]);
UsernameEdit->setReadOnly(true);
data[0].clear();

// // Basic Tab - Dodawanie Widgetow
BasicLayout->addWidget(UsernameLabel);
BasicLayout->addWidget(UsernameEdit);

// // Basic Tab - Ustawianie Layoutu
BasicWidget->setLayout(BasicLayout);

// Tabs
Tabs = new QTabWidget;
Tabs->addTab(BasicWidget, tr("Basic Info"));
MainLayout->addWidget(Tabs);
}

void LoginInterface::Login()
{
data[0] = UserInput->text();
data[1] = PasswordInput->text();

QMessageBox *Box = new QMessageBox;
Box->setWindowTitle("Login");

if(data[0] != "Diath" && data[1] != "test") // have to see QMySQLDriver later
{
Box->setText("You did enter wrong login data.");
Box->setIcon(QMessageBox::Critical);
Box->setStandardButtons(QMessageBox::Ok);
}
else
{
Box->setText("Welcome!");
Box->setIcon(QMessageBox::Information);
Box->setStandardButtons(QMessageBox::Ok);

Run();
}

Box->exec();
}

void LoginInterface::Exit()
{
exit(0);
}


LoginInterface.h:


#ifndef LOGININTERFACE_H
#define LOGININTERFACE_H

#include <QtGui>
#include <QDialog>

class LoginInterface : public QDialog
{
Q_OBJECT
public:
LoginInterface(QWidget *parent = 0, Qt::WindowFlags flags = 0);
public slots:
void Login();
void Exit();
private:
void Run();
QString data[2];

// Main Layout and its controls.
QGridLayout *MainLayout;
QLabel *UserLabel, *PasswordLabel;
QLineEdit *UserInput, *PasswordInput;
QPushButton *LoginButton, *ExitButton;

// Client Layouts and their controls.
QGridLayout *BasicLayout;
QWidget *BasicWidget;
QTabWidget *Tabs;

// Basic Tab
QLabel *UsernameLabel;
QLineEdit *UsernameEdit;
};

#endif // LOGININTERFACE_H


Now, I want to delete MainLayout while deleting old controls like UserInput, and then I have to replace this one:

MainLayout->addWidget(Tabs);

With something that will set Tabs widget as parent windows "central widget", also I have to access somehow to parent window and set its size.

Diath
1st August 2010, 20:03
B.u.m.p. :)

ChrisW67
1st August 2010, 23:04
Your approach at the moment makes more work than you need. To apply a new layout in place of the old you need to delete the existing layout (see QWidget::setLayout() docs) and then apply the new one. That does not remove the original widgets (they are children of the QDialog not the layout) which you would then have to hide or delete yourself. See http://www.qtcentre.org/threads/32951-How-delete-contents-in-QGridLayout?p=152932#post152932

I would use QStackedWidget. In the constructor set up your login user name and password layout on one page and the running stuff on the other and set the login page to be current. Then when they successfully log in switch the stacked layout current page. If there is a log out function then that just switches the pages back.

Diath
2nd August 2010, 00:41
Thanks for your advice, now I have such code so far:

#include "LoginInterface.h"

LoginInterface::LoginInterface(QWidget *parent, Qt::WindowFlags flags) :
QDialog(parent, flags)
{
// Main
MainLayout = new QGridLayout;

// GUI Controls
UserLabel = new QLabel(tr("User:"));
UserInput = new QLineEdit;

PasswordLabel = new QLabel(tr("Password:"));
PasswordInput = new QLineEdit;
PasswordInput->setEchoMode(QLineEdit::Password);

LoginButton = new QPushButton(tr("Login"));
ExitButton = new QPushButton(tr("Exit"));

connect(LoginButton, SIGNAL(clicked()), this, SLOT(Login()));
connect(ExitButton, SIGNAL(clicked()), this, SLOT(Exit()));

// Adding Widgets
MainLayout->addWidget(UserLabel);
MainLayout->addWidget(UserInput);

MainLayout->addWidget(PasswordLabel);
MainLayout->addWidget(PasswordInput);

MainLayout->addWidget(LoginButton);
MainLayout->addWidget(ExitButton);

// Client
ClientLayout = new QGridLayout;
// Basic Tab
BasicWidget = new QWidget;
BasicLayout = new QGridLayout;

// // Basic Tab - Kontrolki
UsernameLabel = new QLabel("User:");
UsernameEdit = new QLineEdit();
UsernameEdit->setReadOnly(true);

// // Basic Tab - Dodawanie Widgetow
BasicLayout->addWidget(UsernameLabel);
BasicLayout->addWidget(UsernameEdit);

// // Basic Tab - Ustawianie Layoutu
BasicWidget->setLayout(BasicLayout);

// Tabs
Tabs = new QTabWidget;

Tabs->addTab(BasicWidget, tr("Basic Info"));

// misc.
ClientLayout->addWidget(Tabs);

setLayout(MainLayout);
setWindowTitle("Login");
}

void LoginInterface::Run()
{
delete UserInput;
delete UserLabel;
delete PasswordInput;
delete PasswordLabel;
delete LoginButton;
delete ExitButton;
delete MainLayout;
// Title
data[1].clear();
data[1] = "Logged as " + data[0];
QWidget::setWindowTitle(data[1]);
data[1].clear();

UsernameEdit->insert(data[0]);
data[0].clear();

// Layout
QWidget::setFixedWidth(250);
QWidget::setLayout(ClientLayout);
}

void LoginInterface::Login()
{
data[0] = UserInput->text();
data[1] = PasswordInput->text();

QMessageBox *Box = new QMessageBox;
Box->setWindowTitle("Login");

if(data[0] != "Diath" && data[1] != "test")
{
Box->setText("You did enter wrong login data.");
Box->setIcon(QMessageBox::Critical);
Box->setStandardButtons(QMessageBox::Ok);
}
else
{
Box->setText("Welcome!");
Box->setIcon(QMessageBox::Information);
Box->setStandardButtons(QMessageBox::Ok);

Run();
}

Box->exec();
delete Box;
}

void LoginInterface::Exit()
{
exit(0);
}


But is there any way to resize QTabWidget like on following screen:
http://img37.imageshack.us/img37/5886/42454570.png

ChrisW67
2nd August 2010, 00:48
Yes.
You really should use Qt Assistant: QLayout::setContentsMargins()

Diath
2nd August 2010, 01:01
Finally, I have excepted result thank you very much :).

Diath
2nd August 2010, 02:57
Oh, I'll probably annoy you guys, but you are much better at explaination and examples than documentation :x.

So, I have file named "resource.rcc" in main project directory, with contents:


<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>res/basic.ico</file>
</qresource>
</RCC>


Also, in main.cpp I have this above QApplication app()~:

Q_INIT_RESOURCE(resource);

Also I have added file to project in Qt Creator, now I'm using following code to insert TAB (this code is in another file named LoginInterface.cpp):

Tabs->addTab(BasicWidget, QIcon(":/res/basic.ico"), tr("Basic Info"));

But after compiling (CTRL+R) and running binary it doesn't seem to work (Just TAB width changed, but I don't see icon.).

Any tips? (A)

ChrisW67
2nd August 2010, 23:58
Add the resource file to the RESOURCES entry in your PRO file and dispense with the Q_INIT_RESOURCE() (unless you have a specific reason you require it).

You might try ":res/basic.ico" as the file name, or make your QRC file read
...
<qresource prefix="/">
...

Diath
3rd August 2010, 10:53
Of course I have resource info in my pro file, it looks like:

QT += core gui

TARGET = client_launcher
TEMPLATE = app

RESOURCES = resource.rcc

SOURCES += \
src/main.cpp \
src/LoginInterface.cpp

HEADERS += \
src/LoginInterface.h

FORMS +=


I tried with ":/res/basic.ico", but then, Qt Creator simply doesn't compile code:

:: error: [obj/qrc_resource.cpp] Error 1

Okay, I've removed Q_INIT_RESOURCE() but I don't think so it helped :D.

Well, I have open Qt Resource System documentation, and saw this example:

QResource::registerResource("/path/to/myresource.rcc");

So I've added in LoginInterface.cpp (in constructor) this:

QResource::registerResource("../myresource.rcc");

(With 2 dots, because my resource file is in higher directory than source files.)
But still I'm failing, any idea? :|

ChrisW67
4th August 2010, 04:12
Assuming a simple application without the complications of dynamically loaded plugins etc. you should not need do anything to register the resource file other than list it in the PRO file. No need to code anything, just use it.


I tried with ":/res/basic.ico", but then, Qt Creator simply doesn't compile code:

:: error: [obj/qrc_resource.cpp] Error 1

I wrote that you might try ":res/basic.ico" as the filename meaning in the cpp source where you load the QIcon, not in the QRC file. Note, there is no "/" between the ":" and the "res". Given that the example below works either way, I doubt this is your problem.

Have you bothered to check if Windows ICO files are listed under QImageReader::supportedImageFormats()?

Here is a complete example:


#include <QtGui>

class MainWindow: public QMainWindow {
public:
MainWindow(QWidget *p = 0): QMainWindow(p) {
QWidget *central = new QWidget(this);
QLabel *widget1 = new QLabel(this);
QPixmap pixmap1(":/res/stop.png");
widget1->setPixmap(pixmap1);
QLabel *widget2 = new QLabel(this);
QPixmap pixmap2(":res/stop.png");
widget2->setPixmap(pixmap2);
QVBoxLayout *layout = new QVBoxLayout(central);
layout->addWidget(widget1);
layout->addWidget(widget2);
central->setLayout(layout);
setCentralWidget(central);
}
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MainWindow m;
m.show();
return app.exec();
}



<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>res/stop.png</file>
</qresource>
</RCC>



TEMPLATE = app
TARGET =
RESOURCES+= simple_example.qrc
SOURCES += main.cpp