質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

テキストボックスに文字を出力したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 341

pythonnoob1

score 16

環境

Python 3.x
RaspberryPi 3 B
PyQt5   

やりたいこと

①テキストボックスに「A」、「B」および「C」を出力したいです。
②QThreadを用いたGUIのコードを作りました。おかしな点があれば教えて下さい。

GUIが起動し、自動ボタンを押してもテキストボックス内に文字が出力されません・・・

作成したコード

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import subprocess
import time
import numpy as np
import cv2
import RPi.GPIO as GPIO





class Tab1Widget(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)

        self.qt_thread = None
        self.running = False


        self.title = "GUI test"
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.initUI()
        self.counter = 0

    def initUI(self):


        super(Tab1Widget, self).__init__()


        btn1 = self.auto_button = QPushButton("自動", self)
        btn2 = self.stop_button = QPushButton("停止", self)

        btn1.clicked.connect(self.auto )
        btn2.clicked.connect(self.stop )

        self.textbox4 = QLineEdit(self)


        label3 = QLabel("自動ドア")
        label4 = QLabel("ドアの状態")

        layoutA = QGridLayout()
        layoutA.addWidget(label4,0,0)
        layoutA.addWidget(self.textbox4,0,1)
        layoutA.addWidget(btn1,1,0)
        layoutA.addWidget(btn2,1,1)

        layoutB = QVBoxLayout()
        layoutB.addWidget(label3)
        layoutB.addLayout(layoutA)

        self.setLayout(layoutB)

        self.show()

    def closeEvent(self, event):
        self.stop()

        if self.qt_thread:
            self.qt_thread.wait(2000) # sleep の 1秒以上待つ


        super().closeEvent(event)

    def stop(self):


        print("cancel")
        self.running = False

    def setCount(self, alpha):
        # 呼び出されたスレッドの確認
        # print("setCount", count, current_thread())
        self.textbox4.setText("{}".format(alpha))


    def auto(self):

        win = self
        win.running = True

        class MyQtThread(QThread):

            sendCount = pyqtSignal(int)
            sendString = pyqtSignal(str)

            def run(self):
                x=1
                while 1:
                    if x==1:
                        alphabet="A"
                        self.sendCount.emit(alphabet)
                        self.sleep(1)
                        x+=1

                    elif x==2:
                        alphabet="B"
                        self.sendCount.emit(alphabet)
                        self.sleep(1)
                        x+=1


                    else:
                        alphabet="C"
                        self.sendCount.emit(alphabet)
                        self.sleep(1)
                        x=x-2




                #for num in range(500):
                    #if not win.running:
                        #break
                    #self.sendCount.emit(num)
                    #self.sleep(1)

        thread = self.qt_thread = MyQtThread()
        thread.moveToThread(thread) # WRONG!
        thread.sendString.connect(self.setCount)

        # XXX: スレッドのイベントループが動いてない為、処理されない例
        # self.stop_button.clicked.connect(thread.terminate)

        # 直接呼び出しは可能(安全ではないかもしれません)
        terminate = lambda: thread.terminate()
        self.stop_button.clicked.connect(terminate)

        # 終了時にストップボタンのスロット解除
        @thread.finished.connect
        def tear_down():
            self.stop_button.clicked.disconnect(terminate)

        thread.start()



        # self.destroyed.connect(thread.terminate)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = Tab1Widget()
    sys.exit(app.exec_())
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

コードは試してませんが、取り急ぎ目に付く間違いは

           sendCount = pyqtSignal(int)
           sendString = pyqtSignal(str)

と定義してるので、文字列を渡す方のシグナルを使います。

-                        self.sendCount.emit(alphabet)
+                        self.sendString.emit(alphabet)

スロットの接続側も併せて変更が必要です
追記: 接続側は sendString.connect となっているのを確認


QThread については、

  • moveToThread は不要
  • terminateで強制終了 → whileループを抜けて終了させる

具体的には

  • ループの条件式を while not self.isInterruptionRequested(): として、
  • 停止処理は thread.requestInterruption() をメインスレッド側で呼び出す。
  • runningフラグは省略できます。

QThread::isInterruptionRequested

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/08 16:39

    ありがとうございます。

    runningrunningのフラグのこと失念しておりました。ありがとうございます。

    whileがネストする場合は、各ループ内に if self.isInterruptionRequested(): return が必要ということですね。
    if self.isInterruptionRequested(): return だけでよろしいのでしょうか?
    ------
    if self.isInterruptionRequested():
    ○○return
    もしくは
    ○○break
    ------
    の意味でしょうか?

    キャンセル

  • 2020/06/08 17:29

    この辺りは、実際の周辺のコードを元に確認した方が良さそうですね。

    ループがネストしてる場合は、break だと内側のループしか抜けないことに注意してください。
    (if self.isInterruptionRequested(): が何処に置かれるかで、意味合いが変わってきます)

    return ではループと共に関数自体の実行もそこで終ります。
    ループを抜けた後に何かコードを実行したい場合は、逆にreturnでは都合が悪く、
    例外機構(try/except)を使ってループを抜ける等、他の対策が必要なことも有ります。

    キャンセル

  • 2020/06/08 18:18

    ありがとうございます。
    また改めてコードを書いてみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る