@DalOpez

Как заблокировать кнопку на время выполнения кода в PyQt5?

Всем привет. Недавно начал работать с PyQt5. Столкнулся с затруднениями при работе с несколькими окнами. На данный момент программа работает следующим образом: после запуска программы появляется окно с кнопкой. При нажатии на кнопку создается окно, в котором отображается прогрессбар. Заполнение прогрессбара требует какого-то времени. Если в это время кликнуть еще раз на кнопку, то окно с прогрессбаром закрывается и открывается новое. Нужно, чтобы на время заполнения прогрессбара кнопка в первом окне блокировалась или при клике на нее не происходило никаких действий, пока не закончится заполнение прогрессбара.
import sys
from PyQt5.QtWidgets import (QWidget, QProgressBar,
    QPushButton, QApplication)
from PyQt5.QtCore import QBasicTimer

class New_window(QWidget):
    def __init__(self):
        super().__init__()

        self.window1()

    def window1(self):
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 200, 25)

        self.timer = QBasicTimer()
        self.step = 0

        self.setWindowTitle('Progressbar')
        self.show()

        self.do()


    def timerEvent(self, e):

        if self.step >= 100:
            self.timer.stop()
            self.close()
            return

        self.step = self.step + 1
        self.pbar.setValue(self.step)

    def do(self):
        if self.timer.isActive():
            self.timer.stop()
            return

        else:
            self.timer.start(10, self)




class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):



        self.btn = QPushButton('Start', self)
        self.btn.move(40, 80)
        self.btn.clicked.connect(self.doAction)



        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('Main')
        self.show()


    def doAction(self):
        self.btn.setEnabled(False)
        self.w1 = New_window()
        self.w1.do()
        self.btn.setEnabled(True)



if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
  • Вопрос задан
  • 1256 просмотров
Пригласить эксперта
Ответы на вопрос 2
Ternick
@Ternick
Ответ легко ищется поисковиком, нужно лишь знать, что спрашивать :)
КУСЬ <- Пункт 4 {setEnabled()}
Если вас устраивает ответ нажмите на кнопку "Отметить решением".
На будущее :
Вот у вас есть некий класс у которого есть метод, который вы благополучно забыли и вам лень лезть в сорсы и искать, то можно использовать встроенную команду help() <- передавать туда только адрес чего-то.
Пример:
>>> from requests import Response
>>> help(Response)
Help on class Response in module requests.models:

class Response(builtins.object)
 |  The :class:`Response <Response>` object, which contains a
 |  server's response to an HTTP request.
 |
 |  Methods defined here:
 |
 |  __bool__(self)
 |      Returns True if :attr:`status_code` is less than 400.
 |
 |      This attribute checks if the status code of the response is between
 |      400 and 600 to see if there was a client error or a server error. If
 |      the status code, is between 200 and 400, this will return True. This
 |      is **not** a check to see if the response code is ``200 OK``.
 |
 |  __enter__(self)
 |
 |  __exit__(self, *args)
 |
 |  __getstate__(self)
 |
 |  __init__(self)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |
 |  __iter__(self)
 |      Allows you to use a response as an iterator.
 |
 |  __nonzero__(self)
-- Далее  --

А Вообще в pyqt5 есть какие-то сигналы и потоки, может это и не относится к делу, но может тебе пригодится в будущем, советую глянуть :)
Ответ написан
sanya84
@sanya84
Фанатик Python 3
import sys
from io import BytesIO
from time import sleep
from PyQt5.QtWidgets import (QWidget, QProgressBar, QDialog,
    QPushButton, QApplication, QVBoxLayout, QLabel, QMessageBox)
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, Qt
from PyQt5.QtGui import QPixmap, QImage
import requests
from PIL import Image
from PIL.ImageQt import ImageQt


# Отловить ошибки в слотах PyQt5
def log_uncaught_exceptions(ex_cls, ex, tb):
    text = '{}: {}:\n'.format(ex_cls.__name__, ex)
    import traceback
    text += ''.join(traceback.format_tb(tb))

    print(text)
    QMessageBox.critical(None, 'Error', text)
    quit()
sys.excepthook = log_uncaught_exceptions


class ProgressWindow(QThread):
	signal = pyqtSignal(int)
	chunk_data = pyqtSignal(bytes)
	url = "http://risovach.ru/upload/2014/02/mem/muzhik-bleat_43233947_orig_.jpg"
	headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"}

	def __init__(self):
		super().__init__()
		self.window = QDialog()
		self.window.setWindowTitle('Progress window')
		self.progress = QProgressBar(self.window)
		self.progress.setGeometry(0, 0, 240, 25)
	def download_file(self, url):
		with requests.get(url, headers=self.headers, stream=True) as response:
			response.raise_for_status()
			file_size = response.headers['content-length'] # 42689
			print(file_size)
			step = 0
			for chunk in response.iter_content(chunk_size=426):
				sleep(0.01)
				step = step + 1
				self.signal.emit(step)
				self.chunk_data.emit(chunk)
			self.signal.emit(0)

	def run(self):
		try:
			self.download_file(self.url)
		except Exception as error:
			print(error)

class MainWindow(QWidget):
	def __init__(self):
		super().__init__()
		self.initUI()
	def initUI(self):
		self.setGeometry(300, 300, 500, 350)
		self.setWindowTitle('Как научиться нормально программировать')
		# self.setWindowModality(Qt.WindowModal)

		vbox = QVBoxLayout(self)

		self.start_button = QPushButton('Узнать', self)
		self.start_button.move(40, 80)
		self.start_button.clicked.connect(self.download)

		self.label_image = QLabel(self)
		vbox.addWidget(self.label_image)
		vbox.addWidget(self.start_button)
		self.setLayout(vbox)

		self.progress_window = ProgressWindow()
		self.progress_window.window.setModal(True)

		self.buffer = BytesIO()
		self.chunk_size = 0

	def download(self):
		self.progress_window.window.show()
		self.progress_window.start()
		self.start_button.setEnabled(False)
		self.progress_window.signal.connect(self.update_progress)
		self.progress_window.chunk_data.connect(self.image_view)

	def update_progress(self, step):
		if step >= 101:
			self.progress_window.window.hide()
			self.progress_window.terminate()
			self.start_button.setEnabled(True)
		else:
			self.progress_window.progress.setValue(step)
	def image_view(self, chunk):
		self.buffer.write(chunk)
		if len(chunk) <= 89:
			pillow_image = Image.open(self.buffer)
			pixmap = QPixmap(pillow_image.toqpixmap())
			self.label_image.setPixmap(pixmap)
			self.label_image.update()

if __name__ == '__main__':
    application = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(application.exec_())
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы