LoginSignup
0
0

More than 1 year has passed since last update.

Qt creator C++ thread

Last updated at Posted at 2022-01-17

sample動作

以下GithubにあるQtのスレッドのサンプルコードを動作させてみました.

手順

1.Qt creatorでプロジェクト作成(今回はcmakeを使用)
2.上記Githubをcloneし,中にあるmainwindow.*ファイルとworker.*ファイルを作成したプロジェクトにコピー
3.CMakeLists.txtを以下のように書き換える

CMakeLists.txt
cmake_minimum_required(VERSION 3.5)

project(jjjj LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

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

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check http://doc.qt.io/qt-5/deployment-android.html for more information.
# They need to be set before the find_package(Qt5 ...) call.

#if(ANDROID)
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
#    if (ANDROID_ABI STREQUAL "armeabi-v7a")
#        set(ANDROID_EXTRA_LIBS
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so![qtsimplethread.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/63154851-55ed-837e-2401-00cf62713d67.gif)

#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
#    endif()
#endif()

find_package(Qt5 COMPONENTS Widgets REQUIRED)

if(ANDROID)
  add_library(jjjj SHARED
    main.cpp
    mainwindow.cpp
    mainwindow.h
    mainwindow.ui
  )
else()
  add_executable(jjjj
    main.cpp
    mainwindow.cpp
    mainwindow.h
    mainwindow.ui

    worker.h # add
    worker.cpp # add
  )
endif()

target_link_libraries(jjjj PRIVATE Qt5::Widgets)

4.実行すると以下のようなGUIが生成されます.

qtsimplethread.gif

別スレッドで1秒毎にカウントを増やし,メインウィジェットのラベルに表示しています。詳しくは今回使用したGihubリポジトリをご参照下さい。

自分で作成したプロジェクトにthread追加

1.qtcreatorでプロジェクト作成
2.labelを配置
3.worker.*をこのプロジェクトにコピー
4.コードを以下のように変更(uiファイルは2でlabelを配置してれば変更の必要なし)

diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0294fd..901a4ce 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,6 +39,9 @@ else()
     mainwindow.cpp
     mainwindow.h
     mainwindow.ui
+
+    worker.h # add
+    worker.cpp # add
   )
 endif()

diff --git a/mainwindow.cpp b/mainwindow.cpp
index a06fc8e..88fe83a 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -1,15 +1,36 @@
 #include "mainwindow.h"
 #include "./ui_mainwindow.h"
+#include <QDebug>

 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
     , ui(new Ui::MainWindow)
 {
     ui->setupUi(this);
+
+    thread = new QThread();
+    worker = new Worker();
+
+    worker->moveToThread(thread);
+    connect(worker, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString)));
+    connect(worker, SIGNAL(workRequested()), thread, SLOT(start()));
+    connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
+    connect(worker, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
+
+    worker->abort();
+    thread->wait(); // If the thread is not running, this will immediately return.
+
+    worker->requestWork();
 }

 MainWindow::~MainWindow()
 {
+    worker->abort();
+    thread->wait();
+    qDebug()<<"Deleting thread and worker in Thread "<<this->QObject::thread()->currentThreadId();
+    delete thread;
+    delete worker;
+
     delete ui;
 }

diff --git a/mainwindow.h b/mainwindow.h
index 4643e32..dae2fab 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -2,6 +2,8 @@
 #define MAINWINDOW_H

 #include <QMainWindow>
+#include <QThread>
+#include "worker.h"

 QT_BEGIN_NAMESPACE
 namespace Ui { class MainWindow; }
@@ -17,5 +19,7 @@ public:

 private:
     Ui::MainWindow *ui;
+    QThread *thread;
+    Worker *worker;
 };
 #endif // MAINWINDOW_H
diff --git a/mainwindow.ui b/mainwindow.ui
index b232854..4356b8e 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -13,8 +13,31 @@
   <property name="windowTitle">
    <string>MainWindow</string>
   </property>
-  <widget class="QWidget" name="centralwidget"/>
-  <widget class="QMenuBar" name="menubar"/>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QLabel" name="label">
+    <property name="geometry">
+     <rect>
+      <x>90</x>
+      <y>290</y>
+      <width>67</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>TextLabel</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>800</width>
+     <height>28</height>
+    </rect>
+   </property>
+  </widget>
   <widget class="QStatusBar" name="statusbar"/>
  </widget>
  <resources/>
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)

project(thread_test LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

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

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
# Check http://doc.qt.io/qt-5/deployment-android.html for more information.
# They need to be set before the find_package(Qt5 ...) call.

#if(ANDROID)
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
#    if (ANDROID_ABI STREQUAL "armeabi-v7a")
#        set(ANDROID_EXTRA_LIBS
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so
#            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
#    endif()
#endif()

find_package(Qt5 COMPONENTS Widgets REQUIRED)

if(ANDROID)
  add_library(thread_test SHARED
    main.cpp
    mainwindow.cpp
    mainwindow.h
    mainwindow.ui
  )
else()
  add_executable(thread_test
    main.cpp
    mainwindow.cpp
    mainwindow.h
    mainwindow.ui

    worker.h # add
    worker.cpp # add
  )
endif()

target_link_libraries(thread_test PRIVATE Qt5::Widgets)
mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    thread = new QThread();
    worker = new Worker();

    worker->moveToThread(thread);
    connect(worker, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString)));
    connect(worker, SIGNAL(workRequested()), thread, SLOT(start()));
    connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
    connect(worker, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);

    worker->abort();
    thread->wait(); // If the thread is not running, this will immediately return.

    worker->requestWork();
}

MainWindow::~MainWindow()
{
    worker->abort();
    thread->wait();
    qDebug()<<"Deleting thread and worker in Thread "<<this->QObject::thread()->currentThreadId();
    delete thread;
    delete worker;

    delete ui;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QThread>
#include "worker.h"

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;
    QThread *thread;
    Worker *worker;
};
#endif // MAINWINDOW_H
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0