Qt creator C++ thread

# sample動作

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

https://github.com/fabienpn/simple-qt-thread-example

### 手順

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


```cmake: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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/97946ae1-3fcc-7ea1-664c-7f04cb9a58b4.gif)

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

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

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

```patch: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/>
```

```cmake: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)
```

```cpp: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;
}
```

```cpp: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
```