主なアイデアは、メインGUIからボタンクリックでプログレスバー(子GUI)を呼び出すことです。メインGUIの「作成」ボタンをクリックすると、次の3つの問題が発生します。
- 実行に失敗することがあります
- 子GUIに「キャンセル」ボタンが表示されない場合があります
- 上記の両方がうまくいけば、キャンセルボタンをクリックできません。
実行に失敗する次のコードがあります。以下のコードは、誰かがコピーして貼り付けて実行できる実際のコードです
import sys
try:
from PyQt4 import QtCore, QtGui
except:
pass
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_dialog_progress(object):
def setupUi(self, dialog_progress):
dialog_progress.setObjectName("dialog_progress")
dialog_progress.resize(401, 165)
self.gridLayout = QtGui.QGridLayout(dialog_progress)
self.gridLayout.setObjectName("gridLayout")
self.lblFileName = QtGui.QLabel(dialog_progress)
self.lblFileName.setText("")
self.lblFileName.setObjectName("lblFileName")
self.gridLayout.addWidget(self.lblFileName, 0, 0, 1, 2)
self.pbarFileSize = QtGui.QProgressBar(dialog_progress)
self.pbarFileSize.setProperty("value", 0)
self.pbarFileSize.setObjectName("pbarFileSize")
self.gridLayout.addWidget(self.pbarFileSize, 1, 0, 1, 2)
self.label_2 = QtGui.QLabel(dialog_progress)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.pbarTotal = QtGui.QProgressBar(dialog_progress)
self.pbarTotal.setProperty("value", 0)
self.pbarTotal.setObjectName("pbarTotal")
self.gridLayout.addWidget(self.pbarTotal, 3, 0, 1, 2)
self.lblTotal = QtGui.QLabel(dialog_progress)
self.lblTotal.setText("")
self.lblTotal.setObjectName("lblTotal")
self.gridLayout.addWidget(self.lblTotal, 4, 0, 1, 2)
spacerItem = QtGui.QSpacerItem(213, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 6, 0, 1, 1)
spacerItem1 = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem1, 5, 1, 1, 1)
self.btnPbarCancel = QtGui.QPushButton(dialog_progress)
self.btnPbarCancel.setObjectName("btnPbarCancel")
self.gridLayout.addWidget(self.btnPbarCancel, 6, 1, 1, 1)
self.retranslateUi(dialog_progress)
QtCore.QMetaObject.connectSlotsByName(dialog_progress)
def retranslateUi(self, dialog_progress):
dialog_progress.setWindowTitle(QtGui.QApplication.translate("dialog_progress", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("dialog_progress", "Total:", None, QtGui.QApplication.UnicodeUTF8))
self.btnPbarCancel.setText(QtGui.QApplication.translate("dialog_progress", "Cancel", None, QtGui.QApplication.UnicodeUTF8))
class ProgressDialog(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent = None)
self.ui = Ui_dialog_progress()
self.ui.setupUi(self)
self.setWindowModality(QtCore.Qt.ApplicationModal)
signal = QtCore.SIGNAL("clicked()")
self.ui.btnPbarCancel.connect(self.ui.btnPbarCancel, signal, self.abort)
def abort(self):
print "abc"
pass
class Ui_dialog_file(object):
def setupUi(self, dialog_file):
dialog_file.setObjectName(_fromUtf8("dialog_file"))
dialog_file.resize(101, 59)
self.btnCreate = QtGui.QPushButton(dialog_file)
self.btnCreate.setGeometry(QtCore.QRect(10, 20, 77, 25))
self.btnCreate.setObjectName(_fromUtf8("btnCreate"))
self.retranslateUi(dialog_file)
QtCore.QMetaObject.connectSlotsByName(dialog_file)
def retranslateUi(self, dialog_file):
dialog_file.setWindowTitle(QtGui.QApplication.translate("dialog_file", "file", None, QtGui.QApplication.UnicodeUTF8))
self.btnCreate.setText(QtGui.QApplication.translate("dialog_file", "Create", None, QtGui.QApplication.UnicodeUTF8))
class Methods():
def __init__(self, summaryFile = None):
pass
def pbar(self):
i = 0
self.pd.ui.pbarTotal.setValue(0)
self.pd.ui.pbarFileSize.setValue(0)
j = 0
while i < 100:
while j < 100:
self.pd.ui.pbarFileSize.setValue(j)
j += 1
i += 1
j = 0
self.pd.ui.pbarTotal.setValue(i)
class Worker(QtCore.QThread, Methods):
def __init__(self, pd = None
):
QtCore.QThread.__init__(self)
self.pd = pd
def __del__(self):
self.wait()
self.exiting = True
def done(self):
self.emit(QtCore.SIGNAL("workerDone()"))
def run(self):
self.pd.show()
self.pbar()
self.pd.hide()
self.pd.destroy()
class App(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.ui = Ui_dialog_file()
self.ui.setupUi(self)
signal = QtCore.SIGNAL("clicked()")
self.connect(self.ui.btnCreate, signal, self.create)
self.pd = None
def create(self):
self.pd = ProgressDialog()
self.worker = Worker(self.pd)
self.worker.start()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
test = App()
test.show()
app.exec_()
新しいコード
import sys
from PyQt4 import QtGui, QtCore
import time
import random
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_dialog_progress(object):
def setupUi(self, dialog_progress):
dialog_progress.setObjectName("dialog_progress")
dialog_progress.resize(401, 165)
self.gridLayout = QtGui.QGridLayout(dialog_progress)
self.gridLayout.setObjectName("gridLayout")
self.lblFileName = QtGui.QLabel(dialog_progress)
self.lblFileName.setText("")
self.lblFileName.setObjectName("lblFileName")
self.gridLayout.addWidget(self.lblFileName, 0, 0, 1, 2)
self.pbarFileSize = QtGui.QProgressBar(dialog_progress)
self.pbarFileSize.setProperty("value", 0)
self.pbarFileSize.setObjectName("pbarFileSize")
self.gridLayout.addWidget(self.pbarFileSize, 1, 0, 1, 2)
self.label_2 = QtGui.QLabel(dialog_progress)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.pbarTotal = QtGui.QProgressBar(dialog_progress)
self.pbarTotal.setProperty("value", 0)
self.pbarTotal.setObjectName("pbarTotal")
self.gridLayout.addWidget(self.pbarTotal, 3, 0, 1, 2)
self.lblTotal = QtGui.QLabel(dialog_progress)
self.lblTotal.setText("")
self.lblTotal.setObjectName("lblTotal")
self.gridLayout.addWidget(self.lblTotal, 4, 0, 1, 2)
spacerItem = QtGui.QSpacerItem(213, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 6, 0, 1, 1)
spacerItem1 = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem1, 5, 1, 1, 1)
self.btnPbarCancel = QtGui.QPushButton(dialog_progress)
self.btnPbarCancel.setObjectName("btnPbarCancel")
self.gridLayout.addWidget(self.btnPbarCancel, 6, 1, 1, 1)
self.retranslateUi(dialog_progress)
QtCore.QMetaObject.connectSlotsByName(dialog_progress)
def retranslateUi(self, dialog_progress):
dialog_progress.setWindowTitle(QtGui.QApplication.translate("dialog_progress", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("dialog_progress", "Total:", None, QtGui.QApplication.UnicodeUTF8))
self.btnPbarCancel.setText(QtGui.QApplication.translate("dialog_progress", "Cancel", None, QtGui.QApplication.UnicodeUTF8))
class ProgressDialog(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent = None)
self.ui = Ui_dialog_progress()
self.ui.setupUi(self)
self.setWindowModality(QtCore.Qt.ApplicationModal)
class MyThread(QtCore.QThread):
trigger = QtCore.pyqtSignal()
trcancel = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(MyThread, self).__init__(parent)
def run(self):
time.sleep(random.random()*5) # random sleep to imitate working
self.trigger.emit()
self.trcancel.emit()
class Ui_dialog_file(object):
def setupUi(self, dialog_file):
dialog_file.setObjectName(_fromUtf8("dialog_file"))
dialog_file.resize(101, 59)
self.btnCreate = QtGui.QPushButton(dialog_file)
self.btnCreate.setGeometry(QtCore.QRect(10, 20, 77, 25))
self.btnCreate.setObjectName(_fromUtf8("btnCreate"))
self.retranslateUi(dialog_file)
QtCore.QMetaObject.connectSlotsByName(dialog_file)
def retranslateUi(self, dialog_file):
dialog_file.setWindowTitle(QtGui.QApplication.translate("dialog_file", "file", None, QtGui.QApplication.UnicodeUTF8))
self.btnCreate.setText(QtGui.QApplication.translate("dialog_file", "Create", None, QtGui.QApplication.UnicodeUTF8))
class Main(QtGui.QDialog):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.ui = Ui_dialog_file()
self.ui.setupUi(self)
self.ui.btnCreate.clicked.connect(self.start_threads)
self.pd = ProgressDialog()
self.pd.ui.btnPbarCancel.clicked.connect(self.stopp)
def start_threads(self):
thread = MyThread(self) # create a thread
thread.trigger.connect(self.pdialog) # connect to it's signal
thread.start()
def pdialog(self):
self.pd.show()
i = 0
self.pd.ui.pbarTotal.setValue(0)
self.pd.ui.pbarFileSize.setValue(0)
j = 1
while i < 100:
while j <= 100:
time.sleep(0.001)
self.pd.ui.pbarFileSize.setValue(j)
j += 1
i += 1
j = 1
self.pd.ui.pbarTotal.setValue(i)
def stopp(self):
print "cancel pressed"
self.pd.hide()
self.pd.destroy()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainwindow = Main()
mainwindow.show()
sys.exit(app.exec_())