Python2.7+PyQt4でスレッド処理



# スレッド処理
プログラムを書いていてスレッド処理をしないといけなくなり、いろいろと調べていたんだけど、なかなか思い通りにならなかったものが、とりあえずスレッド処理が出来るようになったので載せます。

# 画面デザイン
QT Deseignerで作りました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/156294/377304c2-f06a-56a6-7b1d-71e0fa37542a.png)

th_test_ui.py で保存。メインプログラムでimportします。

```python
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(613, 282)
        self.lcdNumber = QtGui.QLCDNumber(Form)
        self.lcdNumber.setGeometry(QtCore.QRect(10, 10, 590, 100))
        self.lcdNumber.setSmallDecimalPoint(True)
        self.lcdNumber.setNumDigits(10)
        self.lcdNumber.setSegmentStyle(QtGui.QLCDNumber.Filled)
        self.lcdNumber.setObjectName(_fromUtf8("lcdNumber"))
        self.lcdNumber_2 = QtGui.QLCDNumber(Form)
        self.lcdNumber_2.setGeometry(QtCore.QRect(10, 160, 590, 100))
        self.lcdNumber_2.setSmallDecimalPoint(True)
        self.lcdNumber_2.setNumDigits(10)
        self.lcdNumber_2.setSegmentStyle(QtGui.QLCDNumber.Filled)
        self.lcdNumber_2.setObjectName(_fromUtf8("lcdNumber_2"))

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
```

#スレッド処理サンプルプログラム
上のLCD表示が1秒ごとに時間が更新され、下のLCD表示が0.5秒ごとに1づつ加算されます。

```python
from PyQt4 import QtGui
from PyQt4 import QtCore
import sys, time

import th_test_ui #画面の読み込み

#global LCD1_count

class MainClass(QtGui.QMainWindow, th_test_ui.Ui_Form): #画面表示用クラス
    def __init__(self,parent=None):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.thread1=LCD1Count(self) #スレッド処理宣言
        self.thread2=LCD2Count(self) #スレッド処理宣言
        self.connect(self.thread1, QtCore.SIGNAL("changeTxt1(QString)"), self.changeTxt1) #シグナルに対する呼び出しを宣言
        self.connect(self.thread2, QtCore.SIGNAL("changeTxt2(QString)"), self.changeTxt2) #シグナルに対する呼び出しを宣言
        self.thread1.start() #スレッド開始
        self.thread2.start() #スレッド開始

    def closeEvent(self,event): #閉じるボタンを押した時の処理
        self.thread1.stop()
        self.thread2.stop()

    def changeTxt1(self,LCD1_count): #lcdNumberに文字列書き込み
        self.lcdNumber.display(LCD1_count)

    def changeTxt2(self,LCD2_count): #lcdNumber_2に文字列書き込み
        self.lcdNumber_2.display(LCD2_count)

class LCD1Count(QtCore.QThread): #1秒毎に時間を返すクラス
    def __init__(self,parent=None):
        QtCore.QThread.__init__(self,parent)
        self.stopFlag = False

    def __del__(self):
        self.quit()

    def stop(self): #ループを抜けるためにフラグ変更
        self.stopFlag = True

    def run(self): #start()で開始するメソッド
        while self.stopFlag == False:
            time.sleep(1)
            self.LCD1_count = QtCore.QDateTime.currentDateTime().toString('hh:mm:ss')
            self.emit(QtCore.SIGNAL("changeTxt1(QString)"),self.LCD1_count)

class LCD2Count(QtCore.QThread): #0.5秒ごとに+1した値を返すクラス
    def __init__(self,parent=None):
        QtCore.QThread.__init__(self,parent)
        self.LCD1_count = 0
        self.stopFlag = False

    def __del__(self):
        self.quit()

    def stop(self): #ループを抜けるためにフラグ変更
        self.stopFlag = True

    def run(self): #start()で開始するメソッド
        while self.stopFlag == False:
            time.sleep(0.5)
            self.LCD1_count += 1
            self.emit(QtCore.SIGNAL("changeTxt2(QString)"),str(self.LCD1_count))
            

def main():
    app = QtGui.QApplication(sys.argv)
    form = MainClass()
    form.show()
    app.exec_()


if __name__ == '__main__':
    main()           
```