Port of 3D Slicer to Qt Julien Finet & Jean-Christophe Fillion-Robin Kitware Inc. June 22 th 2010.
-1- National Alliance for Medical Image Computing First Steps with Qt Julien Finet Kitware Inc. Jan....
-
Upload
agatha-walker -
Category
Documents
-
view
216 -
download
0
Transcript of -1- National Alliance for Medical Image Computing First Steps with Qt Julien Finet Kitware Inc. Jan....
-1-National Alliance for Medical Image Computing
First Steps with Qt
Julien FinetKitware Inc.
Jan. 05th 2010
-2-National Alliance for Medical Image Computing
Hello World!
#include <QApplication>#include <QPushButton>
int main(int argc, char * argv[]){ QApplication app(argc, argv);
QPushButton button(“Hello World”);
button.show();
return app.exec();}
The QApplication object must be created before any GUI-related features of Qt are used.
Enter the loop of events. Qt receives and processes user and system events and passes these on to the appropriate widgets.
-3-National Alliance for Medical Image Computing
Qt classes
QObject
QWidget
QLabelQAbstractButton
QPushButtonQCheckBox
QAction
QPaintDevice
…
…
-4-National Alliance for Medical Image Computing
QObjects
• The QObject class is the base class of all Qt objects• When deleted, the parent deletes its children.
class QObject{public: QObject(QObject * parent = 0);
virtual ~QObject();
const QObjectList & children () const;
void setParent(QObject * parent);};
Add itself to the parent’s children list.
qobject.h
-5-National Alliance for Medical Image Computing
QWidgets
• If a widget’s parent is 0, the widget is a window.• When shown/hidden, the parent shows/hides its children.• When enabled/disabled, the parent enables/disables its
children (except for children explicitly hidden).
-6-National Alliance for Medical Image Computing
QObjects
• QObjects can be safely created on the heap.
• Be careful when instantiating on the stack.
…int main(int argc, char* argv[]){ … QWidget parentWidget; QPushButton* button = new QPushButton(“Hello World”, parentWidget); …}
parentWidget’s destructor deletes button
int main(int argc, char* argv[]){ … QWidget parentWidget; QPushButton button(“Hello World”, & parentWidget); …}
int main(int argc, char* argv[]){ … QPushButton button(“Hello World”); QWidget parentWidget; button.setParent(&parentWidget); …}
Error: button is deleted twiceThe destructor of button is called first, and it removes itself from its parent.
-7-National Alliance for Medical Image Computing
Non QObject
• May be instantiated on the heap or stack.
• It’s safer to create them on the stack.
…QVector<int>* ages;…ages = new QVector<int>(10);…delete ages;…
…QString firstName(“John”);QString lastName(“Doe”);Qvector<int> ages;…ages.resize(10);…
-8-National Alliance for Medical Image Computing
QLayout – Geometry Manager
• Instead of specifying widget coordinates for each QWidget, use QLayouts.
…QGroupBox* parameters = new QGroupBox(“Parameters”, this);QLabel* label = new QLabel(“Number of Iterations:”, parameters);QSpinBox* spinBox = new QSpinBox(parameters);…label->setGeometry(0, 0, 50, 20);spinBox->setGeometry(56, 0, 30, 20);…
…QGroupBox* parameters = new QGroupBox(“Parameters, this);QLabel* label = new QLabel(“Number of Iterations:”, parameters);QSpinBox* spinBox = new QSpinBox(parameters);…QHBoxLayout* layout = new QHBoxLayout;layout->addWidget(label);layout->addWidget(spinBox);parameters->setLayout(layout);…
Without QLayout With QLayout
-9-National Alliance for Medical Image Computing
QLayout class diagram
QObject
QLayout
QStackedLayout
QBoxLayout
QVBoxLayoutQHBoxLayout
QGridLayoutQFormLayout
-10-National Alliance for Medical Image Computing
QLayout Example 1/2
• QHBoxLayout
• QVBoxLayout
…QHBoxLayout* layout = new QHBoxLayout;layout>addWidget(iterationNumberLabel);layout->addWidget(iterationNumberSpinBox);layout->addWidget(thresholdLabel);layout->addWidget(thresholdDoubleSpinBox);parameters->setLayout(layout);…
…QVBoxLayout* layout = new QVBoxLayout;layout>addWidget(iterationNumberLabel);layout->addWidget(iterationNumberSpinBox);layout->addWidget(thresholdLabel);layout->addWidget(thresholdDoubleSpinBox);parameters->setLayout(layout);…
-11-National Alliance for Medical Image Computing
Qlayout Example 2/2
• QGridLayout
• QFormLayout
QGridLayout* layout = new QGridLayout;layout>addWidget(iterationNumberLabel, 0, 0, 1, 1);layout->addWidget(iterationNumberSpinBox , 0, 1, 1, 1);layout->addWidget(thresholdLabel, 1, 0, 1, 1);layout->addWidget(thresholdDoubleSpinBox, 1, 1, 1, 1);parameters->setLayout(layout);…
QFormLayout* layout = new QFormLayout;layout>setWidget(0, QFormLayout::LabelRole, iterationNumberLabel);layout->setWidget(0, QFormLayout::FieldRole, iterationNumberSpinBox);layout->setWidget(1, QFormLayout::LabelRole, thresholdLabel);layout->addWidget(1, QFormLayout::FieldRole, thresholdDoubleSpinBox);parameters->setLayout(layout);…
-12-National Alliance for Medical Image Computing
Signals & Slots
• Qt uses signals and slots for high-level events (listerners) and virtual methods for low-level events
• Type-safe callbacks• Precompiler (moc)• A class which emits a signal neither knows nor cares
which slots receive the signal
-14-National Alliance for Medical Image Computing
Signals & Slots - Example
...class QSlider: public QWidget{ Q_OBJECTpublic: …public slots: void setValue(int value); …signals: void valueChanged(int value); …};
…void QSlider::setValue(int value){ … if (value != old) { emit valueChanged(value); }}…
valueChanged() is not defined
…int main(…){ … QSpinBox* spinBox = new QSpinBox(panel); QSlider* slider = new QSlider(panel); … QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue (int))); QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue (int))); …}
...class QSpinBox: public QWidget{ Q_OBJECTpublic: …public slots: void setValue(int value); …signals: void valueChanged(int value); …};
…void QSlider::setValue(int value){ … if (value != old) { emit valueChanged(value); }}…
QSpinBox.h QSpinBox.cpp
-15-National Alliance for Medical Image Computing
Signals & Slots - ExamplePROJECT(MyProject)
FIND_PACKAGE(Qt4 REQUIRED)INCLUDE(${QT_USE_FILE})
SET(MyProject_SRCS MyWidget.cxx main.cxx)SET(MyProject_MOC_SRCS MyWidget.h)
QT4_WRAP_CPP(MyProject_SRCS ${MyProject_MOC_SRCS})
ADD_EXECUTABLE( MyProject ${MyProject_SRCS})
TARGET_LINK_LIBRARIES(MyProject ${QT_LIBRARIES})
#include <QWidget>class MyWidget: public QWidget{ Q_OBJECTpublic: MyWidget(QWidget* parent = 0);public slots: void setValue(int value);signals: void valueChanged(int value);private: int Value;};
#include “MyWidget.h”
void MyWidget::MyWidget(QWidget* parent) : QWidget(parent){}
void MyWidget::setValue(int value){ if (value != this->Value) { value = this->Value; emit this->valueChanged(this->Value); }}MyWidget.h
MyWidget.cxx
CMakeLists.cxx
#include <QApplication>#include “MyWidget.h”
int maint(int argc, char* argv[]){ QApplication app(argc, argv); QGroupBox container; MyWidget w1(&container); MyWidget w2(&container);
QObject::connect(w1, SIGNAL(valueChanged(int)), w2, SLOT(setValue(int))); container.show(); return app.exec();} main.cxx
-16-National Alliance for Medical Image Computing
Signals & Slots – Good to remember 1
• Every connection you make emits a signal– duplicate connections emit two signals.
– break a connection using disconnect()• You can connect a signal to a signal
• Signals can have default values
• _
…QObject::connect(loginPushbutton, SIGNAL(clicked()), this, SIGNAL(loginRequested()));…
class MyWidget: public QObject{ …signals: void mySignal(int value = 5); …};
… emit mySignal(); … emit mySignal(10); …
…QObject::connect(button, SIGNAL(clicked()), widget2, SLOT(updateScreen()));…QObject::connect(button, SIGNAL(clicked()), widget2, SLOT(updateScreen()));…
MyWidget.hMyWidget.cxx
-17-National Alliance for Medical Image Computing
Signals & Slots – Good to remember 2
• Slots are implemented as normal methods– Slots can be virtual, public, protected, private.
• Slot may have a shorter signature than the signal it receives– slots can ignore extra arguments.
class MyWidget: public QObject{ …protected slots: virtual void myAbstractSlot() = 0; …};
…QObject::connect(pushButton, SIGNAL(clicked()), this, SLOT(myAbstractSlot()));…
…QObject::connect(slider, SIGNAL(valueChanged(int)), this, SLOT(update()));…
MyWidget.hMyWidget.cxx
-19-National Alliance for Medical Image Computing
QtDesigner- Example
…SET(MyProject_UI_SRCS Resources/UI/MyProject.ui)…QT4_WRAP_UI(MyProject_UI_CXX ${MyProject_UI_SRCS})…
#include <QWidget>#include “ui_MyWidget.h”
class MyWidget: public Qwidget, Ui_MyWidget{ …};
#include “MyWidget.h”#include “"ui_MyWidget.h”
void MyWidget::MyWidget(QWidget* parent) : QWidget(parent){ this->setupUi(this);}
MyWidget.h
MyWidget.cxx
CMakeLists.cxx
#include <QApplication>#include “MyWidget.h”
int maint(int argc, char* argv[]){ QApplication app(argc, argv); MyWidget w(0); w.show(); return app.exec();} main.cxx