QT笔记:多线程和信号槽

QT笔记:多线程和信号槽

多线程

创建多线程有两种方法,一般推荐用moveToThread方法

参考代码如下:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QApplication>


QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;


};



#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include "my_thread.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // MainWindow w;
    // w.show();
    QThread my_thread;
    Worker worker(20);

    QObject::connect(&my_thread,&QThread::started,&worker,&Worker::doWork);

    worker.moveToThread(&my_thread);

    my_thread.start();

    uint32_t main_count=10;
    for(uint32_t i=0; i<main_count;i++ )
    {
        qDebug() << "main runing count:"<<i;
        QThread::msleep(1000);
    }


    my_thread.quit();
    my_thread.wait();


    return a.exec();

}

my_thread.cpp

#include "my_thread.h"


Worker::Worker(uint32_t count)
{
    count_number=count;
}


void Worker::doWork() {

    for(uint32_t i=0; i<count_number;i++ )
    {
        qDebug() << "Thread runing count:"<<i;
        QThread::msleep(1000);
    }
    emit resultReady();

}

CMakerLists.txt

cmake_minimum_required(VERSION 3.5)

project(Thread_test VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(Thread_test
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
        my_thread.h my_thread.cpp
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET Thread_test APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(Thread_test SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(Thread_test
            ${PROJECT_SOURCES}
        )
    endif()
endif()

target_link_libraries(Thread_test PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.Thread_test)
endif()
set_target_properties(Thread_test PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

include(GNUInstallDirs)
install(TARGETS Thread_test
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(Thread_test)
endif()

信号槽

QT通过信号槽机制进行类似中断事件的交互,实际效果跟消息队列类似,可以很好的完成线程同步问题,使用方法类似如下:

槽写法:

QObject::connect(&my_thread,&QThread::started,&worker,&Worker::doWork);

信号写法:

//在类定义里面定义信号
signals:
    void resultReady();

//在实际程序中发射信号
emit resultReady();

posted on 2024-01-23 11:35  不回本不改名  阅读(88)  评论(0编辑  收藏  举报

导航