PyQt プログレスバー ②

PyQt プログレスバー ②

Threadを最も簡単に使う

前回の記事で述べたように、プログレスバーというのは少し扱いが厄介です。

プログレスバーを表示させるということは、なんらかの待ち時間が発生しており、その時になにも動かしていないと「応答待ち」になってしまいます。

これはユーザーにとって、「プログラムが止まった」と思わせてしまうので非常によくありません。

こうなってくるとスレッドさんにご登場していただくしかありません。

動作

まずは、どのように動くかを見てください。

ボタン押下でスタート

ちなみにこのプログレスバーのことをMarquee表示というらしいです。

ソースコード

import sys,time,threading
from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
	def setupUi(self, Form):
		Form.setObjectName("Form")
		Form.resize(530, 239)
		##プログレスバーの設定
		self.progressBar = QtWidgets.QProgressBar(Form)
		self.progressBar.setGeometry(QtCore.QRect(30, 20, 381, 71))
		self.progressBar.setTextVisible(False)
		self.progressBar.setObjectName("progressBar")
		self.pushButton = QtWidgets.QPushButton(Form)
		##ボタンの設定
		self.pushButton.setGeometry(QtCore.QRect(130, 130, 200, 61))
		font = QtGui.QFont()
		font.setPointSize(24)
		self.pushButton.setFont(font)
		self.pushButton.setObjectName("pushButton")
		##ラベルの設定
		self.label = QtWidgets.QLabel(Form)
		self.label.setGeometry(QtCore.QRect(440, 20, 51, 81))
		self.label.setFont(font)
		self.label.setObjectName("label")

		self.retranslateUi(Form)
		##ボタンにイベント割り付け
		self.pushButton.clicked.connect(Form.button_click)
		QtCore.QMetaObject.connectSlotsByName(Form)

	def retranslateUi(self, Form):
		_translate = QtCore.QCoreApplication.translate
		Form.setWindowTitle(_translate("Form", "Form"))
		self.pushButton.setText(_translate("Form", "Push"))
		self.label.setText(_translate("Form", "0%"))

class progress_main(QtWidgets.QDialog):
	def __init__(self,parent=None):
		QtWidgets.QDialog.__init__(self,parent)
		self.progress=Ui_Form()
		self.progress.setupUi(self)
		self.progress.retranslateUi(self)
		self.num =0 #カウント & 進捗表示用の変数
		
	def th(self):#スレッド化される関数
		while self.num <=100:#100回まわす
			self.progress.label.setText(str(self.num)+"%")#ラベルの書き換え
			self.num +=1#インクリメント
			time.sleep(0.1)#0.1秒待ちを入れる。100回なので10秒
		if self.num == 101:#100超えたら終了させる
			self.num=0
			self.progress.label.setText(str(self.num)+"%")
			self.progress.progressBar.setMaximum(100)

	def button_click(self):#ボタンを押した時に動く関数
		self.progress.progressBar.setMaximum(0)#ここで入れることで見た目が映える
		th1 = threading.Thread(target=self.th)#関数thをスレッド化してth1とする
		th1.start()#スレッドスタート

if __name__ == '__main__':
	app = QtWidgets.QApplication(sys.argv)
	window = progress_main()
	window.show()
	
	app.exec_()

詳細

ほとんどの重要事項はソースコードにコメントで書いています。

progressBar.setMaximum(0)

上記の文があることで、プログレスバーをMarquee表示にできます。

終わりに

結果としてスレッドを使ってしまいましたが、かなり簡単な構造だったはずです。

今回は時間待ちでしたが、他の処理(通信など)で待ちが入ってしまっても「応答待ち」になってしまいます。

GUIって難しいですね...

今回載せた2つの方法がなにかの役に立てば幸いです。

ではまたの機会に!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です