SIGNAL is not emitted - c++

I have issue with SIGNAL not being emitted. Here is minimal example of this issue:
main.cpp - standard main
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QVBoxLayout>
#include "combobox.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
QWidget *mainWidget = new QWidget;
setCentralWidget(mainWidget);
QVBoxLayout *mainLayout = new QVBoxLayout;
combobox combo_box;
mainLayout->addWidget(combo_box.box);
mainWidget->setLayout(mainLayout);
}
MainWindow::~MainWindow()
{
}
combobox.h
#ifndef COMBOBOX_H
#define COMBOBOX_H
#include <QComboBox>
#include <QDebug>
class combobox : public QWidget
{
Q_OBJECT
public:
combobox();
~combobox();
QComboBox *box = new QComboBox;
public slots:
void selection_changed();
};
#endif // COMBOBOX_H
combobox.cpp
#include "combobox.h"
combobox::combobox()
{
QString string = "test 1";
box->addItem(string);
string = "test 2";
box->addItem(string);
box->setCurrentIndex(0);
connect(box, SIGNAL(currentIndexChanged(int)), this, SLOT(selection_changed()));
}
combobox::~combobox()
{
}
void combobox::selection_changed()
{
qDebug() << "Selection changed";
box->setCurrentIndex(-1);
}
You need to run qmake before compiling.
When I run this program and change combobox index selection_changed is not executed. Why?
SIGNAL and SLOT connection definitely works, because if I add box->setCurrentIndex(1); at the end of combobox constructor, selection_changed will be executed once.
I am using QT 5.4 with QT Creator
Thanks in advance!

This problem because of you create your ComboBox class object at stack. So if you write some debug information at destructor of this class you can see object destroyed immediately after MainWindow constructor out of scope:
ComboBox::~ComboBox()
{
qDebug() << Q_FUNC_INFO;
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
QWidget *mainWidget = new QWidget;
setCentralWidget(mainWidget);
QVBoxLayout *mainLayout = new QVBoxLayout;
ComboBox combo_box;
mainLayout->addWidget(combo_box.box);
mainWidget->setLayout(mainLayout);
qDebug() << Q_FUNC_INFO;
}
And qDebug() got the following result:
MainWindow::MainWindow(QWidget*)
virtual ComboBox::~ComboBox()
Thats why signal don't emitted. So you need create object on the heap or make something tricks.
Also, you have dynamically allocated object *box at your ComboBox class and don't specify parent of this object, so it seems memory leak is possible. Specify parent or delete object at destructor of ComboBox class.

Related

QT6 - signal/slot between 2 classes

I have created a new class for qpushbutton, I am trying to establish signal slot communication between this class and my mainwindow class
connect(&MyPushButton, &pushbutton::pb_isChecked, this, &MainWindow::MainWindowPBClicked, Qt::DirectConnection);
I used this code but as output only
qDebug("pushButtonClicked");
I can get this output. After that, the slot I called with "emit" does not work.
void pushbutton::pushButtonClicked()
{
if (isChecked())
{
qDebug("pushButtonClicked");
**emit pb_isChecked();**
}
}
all code in my project;
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow ui;
ui.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include "pushbutton.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void MainWindowPBClicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
pushbutton MyPushButton;
connect(&MyPushButton, &pushbutton::pb_isChecked, this, &MainWindow::MainWindowPBClicked, Qt::DirectConnection);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::MainWindowPBClicked()
{
qDebug("MainWindowPBClicked");
}
pushbutton.h
#ifndef PUSHBUTTON_H
#define PUSHBUTTON_H
#include <QWidget>
#include <QPushButton>
class pushbutton : public QPushButton
{
Q_OBJECT
public:
explicit pushbutton(QWidget *parent = nullptr);
public slots:
void pushButtonClicked();
signals:
void pb_isChecked();
};
#endif // PUSHBUTTON_H
pushbutton.cpp
#include "pushbutton.h"
#include "mainwindow.h"
pushbutton::pushbutton(QWidget *parent)
: QPushButton{parent}
{
setAcceptDrops(true);
connect(this, &QPushButton::clicked, [this]() {
pushButtonClicked();
});
}
void pushbutton::pushButtonClicked()
{
if (isChecked())
{
qDebug("pushButtonClicked");
emit pb_isChecked();
}
}
CASE 1: Not creating button in UI file:
In your class MainWindow, variable MyPushButton is a local variable that gets destroyed after it end its scope in constructor. You need to create a dynamic variable of pushButton like this:
pushbutton *MyPushButton = new pushButton(this);
connect(MyPushButton, SIGNAL(pb_isChecked()), this, SLOT(MainWindowPBClicked()), Qt::DirectConnection);
CASE 2: Creating button in UI file:
In this case you cannot use your custom signal pb_isChecked(). You will need to use standard QPushButton signal such as clicked()
connect(ui->MyPushButton, SIGNAL(clicked()), this, SLOT(MainWindowPBClicked()), Qt::DirectConnection);

How to send variables between classes in Qt

I have a problem. I created two classes in my Qt project. One as the main window, and second as the settings dialog. My idea is to send the values from "Settings" to "MainWindow" (like from one TextEdit to another) but unfortunately, I have no idea how to do it. It's confusing me. I have read similar topics on the internet but none of them gives me a clear answer. Can someone help me understand the way how can I do it via example?
I have no useful code to place it here, so I will put the part of the source code and headers of mine.
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
[...]
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "settings.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow()
[...]
private:
Ui::MainWindow *ui;
[...]
};
#endif // MAINWINDOW_H
settings.cpp
#include "settings.h"
#include "ui_settings.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
Settings::Settings(QWidget *parent) :
QDialog(parent),
ui(new Ui::Settings)
{
ui->setupUi(this);
}
settings.h
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QDialog>
namespace Ui {
class Settings;
}
class Settings : public QDialog
{
Q_OBJECT
public:
explicit Settings(QWidget *parent = nullptr);
~Settings();
[...]
private:
Ui::Settings *ui;
[...]
};
#endif // SETTINGS_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Use signals/slots mechanism to share values between two QObject.
For example:
The following code allows yout to send the value in a QLineEdit to another widget by clicking on a button:
class Widget1: public QWidget
{
Q_OBJECT
public:
Widget1(): QWidget(),
message(new QLineEdit())
{
QPushButton* button = new QPushButton("Send msg", this);
connect(button, &QPushButton::clicked, this, [=]() { emit this->sendMsg(message->text());}); // When you click on the button, it will emit the signal sendMsg
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(message);
layout->addWidget(button);
}
private:
QLineEdit* message;
signals:
void sendMsg(QString const& msg);
};
class Widget2: public QWidget
{
Q_OBJECT
public:
Widget2(): QWidget(),
display(new QLabel("Nothing to display", this))
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(display);
}
private:
QLabel* display;
public slots:
void receive(QString const& message)
{
display->setText(message); // When called, display the message in the label
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget* mainWidget = new QWidget();
QHBoxLayout* layout = new QHBoxLayout(mainWidget);
Widget1* w1 = new Widget1();
Widget2* w2 = new Widget2();
layout->addWidget(w1);
layout->addWidget(w2);
// When the signal sendMsg is emitted, call the slot receive
QObject::connect(w1, &Widget1::sendMsg, w2, &Widget2::receive);
mainWidget->show();
return app.exec();
}
There are multiple ways to achieve this.
For example you can provide the public Getter Methods in your dialog for provide value to the public and use them directly in the MainWindow to read those.
Or you can use Signals/Slots as stated above.
One example with Signal/Slots:
The SettingsWindow emits textEdit(QString) signal if Dialog Accepted, and MainWindow receives this signal via on_textEdit(QString) slot and writes it to its own text field:
SettingsWindow reading text input and emitting signal textEdit(QString):
MainWindow receiving signal via slot on_textEdit(QString):
And this is the code:
maindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_textEdited(QString txt);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsdialog.h"
#include <memory>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
auto dlg = new SettingsDialog{this};
connect(dlg, &SettingsDialog::textEdit, this, &MainWindow::on_textEdited);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
}
void MainWindow::on_textEdited(QString txt)
{
ui->textEdit->setText(txt);
}
settingsdialog.h
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QDialog>
namespace Ui {
class SettingsDialog;
}
class SettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit SettingsDialog(QWidget *parent = nullptr);
~SettingsDialog();
signals:
void textEdit(QString txt);
private slots:
void on_buttonBox_accepted();
private:
Ui::SettingsDialog *ui;
};
#endif // SETTINGSDIALOG_H
settingsdialog.cpp
#include "settingsdialog.h"
#include "ui_settingsdialog.h"
SettingsDialog::SettingsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SettingsDialog)
{
ui->setupUi(this);
}
SettingsDialog::~SettingsDialog()
{
delete ui;
}
void SettingsDialog::on_buttonBox_accepted()
{
emit textEdit(ui->textEdit->toPlainText());
}
More about Signal/Slots

hiding the main Window after opening the secondWindow?Also, when the secondWindow is closed by the user, how can the main window reappear?

Basically, when second window is opened from a push button in the main window, the main window will be closed. When the second window is closed, the main window will reappear.
QWidget *wdg = new QWidget;
wdg->show();
hide();
I put this under the class of mainwindow.cpp
I tried using this..but it doesn't seem to do anything?
this are the code I have so far. Everything is working but I just don't know how to hide the window when the second window is opened and also when the second window is closed the main window will reappear.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
public:
void show();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
secwindow.h
#ifndef SECWINDOW_H
#define SECWINDOW_H
#include <QDialog>
namespace Ui {
class SecWindow;
}
class SecWindow : public QDialog
{
Q_OBJECT
public:
explicit SecWindow(QWidget *parent = nullptr);
~SecWindow();
private:
Ui::SecWindow *ui;
};
#endif // SECWINDOW_H
source code
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPixmap>
#include "secwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPixmap pix("C:/Users/Charlene/Downloads/Charlene Back-up/MAPUA/2nd Term/Object Oriented Programming/GOW-Gui/GOW-GUI/intro pic/intro.png");
ui->label->setPixmap(pix.scaled(230,250,Qt::KeepAspectRatio));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked() // Modal approach..mainwindow cannot be moved when secwindow is displayed.
{
SecWindow secwindow;
secwindow.setModal(true); //it'll set the secwindow
secwindow.exec(); //shows secwindow when button is pressed
}
secwindow.cpp
#include "secwindow.h"
#include "ui_secwindow.h"
SecWindow::SecWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::SecWindow)
{
ui->setupUi(this);
}
SecWindow::~SecWindow()
{
delete ui;
}
EDIT:
#Serhiy Kulish
What I added so far:
secWindow.h
class Dialog : public QDialog
{
Dialog();
};
mainwindow.cpp
#include <QDialog>
void MainWindow::show()
{
Dialog *dialog = new Dialog(this); //Error:no matching constructor for initialization of 'Diaolog'
connect(dialog, SIGNAL(accepted()), this, SLOT(show()));
connect(dialog, SIGNAL(rejected()), this, SLOT(show()));
dialog->show();
hide();
}
These are the errors I'm having so far.
Add your own class derived from QDialog. Then connect signals accepted and rejected with MainWindow::show().
Dialog *dialog = new Dialog(this);
connect(dialog, SIGNAL(accepted()), this, SLOT(show()));
connect(dialog, SIGNAL(rejected()), this, SLOT(show()));
dialog->show();
hide();
It works fine on Windows 10.
Also, depends your OS you maybe need
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(false);
in main.cpp to prevent app closing. But in this case you have to quit from your app manually

QT message box not popus on button click

I just started learning QT and what i wanted to accomplish is to get popup message on buttons click.
Here is how my file looks like:
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QDialog>
#include <QLabel>
#include <QMessageBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow *mainWindow = new MainWindow();
QLabel *text = new QLabel("Some text");
QPushButton *btn = new QPushButton("Click");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(btn);
layout->addWidget(text);
QObject::connect(btn, SIGNAL(clicked()), &app, SLOT(popup()));
mainWindow->setLayout(layout);
mainWindow->show();
return app.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::popUp()
{
QMessageBox::information(this, "New Box", "Message");
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMessageBox>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void popUp();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Can you please explain what i've done wrong or maybe there is something missing in my code.
I recommend that the graphical part implement it inside the class MainWindow since the member ui that is private handles the design.
#include <QMessageBox>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QLabel *text = new QLabel("Some text");
QPushButton *btn = new QPushButton("Click");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(btn);
layout->addWidget(text);
ui->centralWidget->setLayout(layout);
connect(btn, &QPushButton::clicked, this, &MainWindow::popUp);
}
Do not make any changes to main.cpp, the code should look like this:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Wrong connection. You should connect the clicked() signal to the mainWindow's slot popUp(), because it is a member of the MainWindow class. And don't forget about case sensitivity of c++ (popUp, not popup):
QObject::connect(btn, SIGNAL(clicked()), mainWindow, SLOT(popUp()));
You're connecting to a private slot from outside mainwindow.
The application output probably shows you a warning like this:
QObject::connect: No such slot QApplication::popup()
Usually what you'd want to do is put stuff used inside mainwindow, inside mainwindow class.
Eg: Create the layout inside the constructor.
You can use the parent argument when creating the objects to get them destroyed when you're done with mainwindow.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QLabel *text = new QLabel("Some text", this);
QPushButton *btn = new QPushButton("Click", this);
QHBoxLayout *layout = new QHBoxLayout;
QObject::connect(btn, SIGNAL(clicked()), this, SLOT(popUp()));
ui->centralWidget->setLayout(layout);
this->show();
}
You have to use ui->centralWidget, because that's how mainwindow works. The application output should have given you a warning for that as well.
Like this:
QWidget::setLayout: Attempting to set QLayout "" on MainWindow "MainWindow", which already has a layout
Ok, you have to work on the file mainwindow.cpp. You have already create the slot, so connect it adding this code in MainWindow's constructor (if you don't know witch is the mw constructor it is the function where is written ui->setupUi(this);)
connect(ui->btn, SIGNAL(clicked()), SLOT(popUp()));
now in the slot MainWindow::popUp(); put this code:
QMessageBox msgBox;
msgBox.setText("text to write");
msgBox.exec();
remember to include QMessageBox in mainwindow.cpp, you shouldn't write code on main.cpp, it must be this:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

Qt Closing Previous Window

So this is the code of the main.cpp:
#include <QApplication>
#include <QtGui>
#include <mainwidget.h>
int main(int argc, char **argv)
{
QPushButton button ("Hello world!");
button.show();
mainWidget widget;
widget.show();
return app.exec();
}
I want a button from the "widget" to close the "Hello world!" window. I have already added that button in "widget" and made a function for it in mainwidget.h (which also shows a message box) and connected them. I just want to know how can that same button close the Hello World window. I guess I have to add something to the function in mainwidget.h but I don't know what it is. The instructor says we should use the QWidget close() function.
I will answer to your question but before I'll explain you how a basic Qt application looks like.
In Qt, a basic main is like :
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Here as you can see a QApplication is created then a MainWindow.
So What's the MainWindow class ?
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
It's the MainWindow.h. As you can see MainWindow inherit to the QMainWindow class. It's the main window class to create a graphic user interface.
the Q_OBJECT define is for qmake. Indeed qmake I'll create a moc_mainwindow.cpp for this class to manage the Qt signals.
Now you get an empty window if you create an Empty constructor and destructor like:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
}
MainWindow::~MainWindow()
{
}
then after you wish to write "Hello world !" in the window so in Qt to write a text you can use a QLabel. So to write "Hello World !" you get:
#include "mainwindow.h"
#include <QLabel>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QWidget *widget = new QLabel("Hello world !", this);
}
MainWindow::~MainWindow()
{
}
then after to create a button as you made you ll use the QPushButton class.
so you get:
#include "mainwindow.h"
#include <QLabel>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QWidget *widget = new QLabel("Hello world !", this);
setCentralWidget(widget);
QPushButton *button = new QPushButton("close", this);
}
MainWindow::~MainWindow()
{
}
(I Choose to set the QLabel to the central Widget to don't get the label behind the button but after and in real Qt application a QMainWindow's central widget is mostly usualy a QWidget I'll explain you why after)
now you have a button. But when you click on it nothing append.
Why ? Because nothing link the Button and the Window. to link it in Qt we use the connect function. [http://qt-project.org/doc/qt-4.8/qobject.html][1]
so with connect to close the window when you click on the button you get:
#include "mainwindow.h"
#include <QLabel>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QWidget *widget = new QLabel("Hello world !", this);
setCentralWidget(widget);
QPushButton *button = new QPushButton("close", this);
connect(button, SIGNAL(clicked()), this, SLOT(close()));
}
MainWindow::~MainWindow()
{
}
As you can see with connect. In first parameter, we put the object which ll send the signal here the button. in second parameter, we put the signal to link here it's clicked() to do this we write SIGNAL(clicked()). In third, the object which will receive the signal, here the window to close. In fourth parameter the function to launch when the signal is received. We write this SLOT(close()).
Why SIGNAL and SLOT ? because in Qt to create a signal we use signal: in the .hh and to create a slot et use (public or protected or private) slots:
example:
Class Object
{
Q_OBJECT
...
signals:
void aSignal();
public slots:
void aSlot();
...
};
NOTE: the signal and the slot must have same return and parameters.
after to organize your objects you ll use the labels in the QWidget in the centralWidget so you have:
#include "mainwindow.h"
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QWidget* centralWid = new QWidget(this);
setCentralWidget(centralWid);
QVBoxLayout *layout = new QVBoxLayout(centralWid);
QWidget *widget = new QLabel("Hello world !", this);
QPushButton *button = new QPushButton("close", this);
layout->addWidget(widget);
layout->addWidget(button);
centralWid->setLayout(layout);
connect(button, SIGNAL(clicked()), this, SLOT(close()));
}
MainWindow::~MainWindow()
{
}