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が生成されます.
別スレッドで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