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
