Qt 笔记
This works for developing Qt project with Qt designer and CMake.
CMakeLists.txt for Qt developing
A example:
cmake_minimum_required(VERSION 3.1)
project("Example")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5 COMPONENTS Gui REQUIRED)
file(GLOB example_HEADER source/*.h)
file(GLOB example_UIS ui/*.ui)
qt5_wrap_ui(example_UIS ${example_UIS})
file(GLOB example_SRC source/*.cpp)
add_executable(example ${example_HEADER} ${example_SRC} ${example_UIS})
target_link_libraries(example Qt5::Core Qt5::Widgets Qt5::Gui)
Qt's documentation includes information on which component to include for each class.
Some lines are explained below.
Pre-process .ui
files into c++ header
file(GLOB uis *.ui)
qt5_wrap_ui(uis ${uis})
add_executable(example ${uis} ...)
Custom widgets
Inherit from QWidgets and set up ui in constructor
#include "ui_form.h"
class MyWidget: public QWidget {
private:
Ui::Form ui;
public:
MyWidget(QWidget* parent = nullptr): QWidget(parent) {
ui.setupUi(this);
}
};
Dynamically add widgets
Example of adding widget to grid layout:
QGridLayout *grid = findChild<QGridLayout *>("yourObjectName");
grid->addWidget(widget, 0, 0, 1, 1);
Key press & release event
In the custom widget, override event()
or eventfilter()
Note: tab key press is handled specially by Qt framework. It's catchable by the window only when child widgets cannot get focus
Signal & Slot
Declare & Defination
For a widget to have custom slot, Q_OBJECT
macro must be used.
class MyWidget: public QWidget {
Q_OBJECT
...
signals:
void clicked();
public slots:
void slotFoo() {
}
};
Then add this to CMakeLists.txt so that the macro can be processed:
set(CMAKE_AUTOMOC ON)
Connect
Signals and slots can be connected using connect()
. Or you can specify the connections in Qt Designer.
Parameter of signal
To use a type in queued signal & slot connection (pass as param of signal):
- use macro
Q_DECLARE_METATYPE(T)
after declaring the type - call
qRegisterMetaType<T>()
in main function
Threads
Sub-classing QThread
- put works in
run()
- or, call
exec()
inrun()
and handle works via signal & slots- in destructor, call
quit()
andwait()
to make sure the event loop exits
- in destructor, call
Thread affinity
An QObject have a thread affinity (lives in a certain thread). By default this is the thread it's created in.
Notes: QTcpSocket
and QUdpSocket
are said to work only in thread where they are created. Even calling moveToThread()
doesn't help.
About slots & signals
Different connection type decides which thread the slot is executed on:
- queued: where receiver lives
- direct: where the signal is emitted (not where the sender lives)
- auto (default): if same thread, then direct, else queued