D
D
DalOpez2020-08-05 15:32:29
Python
DalOpez, 2020-08-05 15:32:29

How to block a button for the duration of code execution in PyQt5?

Hello. Recently started working with PyQt5. I'm having trouble with multiple windows. At the moment, the program works as follows: after starting the program, a window with a button appears. When you click on the button, a window is created in which the progress bar is displayed. Filling the progressbar takes some time. If at this time you click again on the button, the window with the progress bar closes and a new one opens. It is necessary that while the progressbar is being filled, the button in the first window is blocked, or when you click on it, no action will occur until the progressbar is filled.

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_())

Answer the question

In order to leave comments, you need to log in

6 answer(s)
T
Ternick, 2020-08-05
@Ternick

The answer is easily found by a search engine, you just need to know what to ask :)
KUS <- Item 4 {setEnabled()}
If you are satisfied with the answer, click on the "Mark as solved" button.
For the future:
Here you have a certain class that has a method that you have safely forgotten and you are too lazy to go into the sources and look for, then you can use the built-in help() command <- pass only the address of something there.
Example:

>>> 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)
-- Далее  --

In general, there are some signals and flows in pyqt5, maybe this is not relevant, but it may come in handy in the future, I advise you to take a look :)

A
Alexander, 2020-08-09
@sanya84

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_())

V
Vitaly Leshchenko, 2015-02-28
@leschenko

OneDrive.
There are clients for Windows, Windows Phone, OSX, iOS, Android.
The basic package gives 15Gb instead of 2Gb for Dropbox.
Extra space is cheaper than Dropbox.
Having an Office 365 Home subscription gives 1Tb of OneDrive space for each family member (up to 5 people).

F
FalKeN, 2015-03-01
@FalKeN

Mega.co.nz 50 gb for free + security + web,linux,windows,android

D
Denis Verbin, 2015-03-01
@rez0n

I chose for myself for a long time, as a result I came to the 2 final versions of DropBox and Google Drive.
DropBox is inherently the most adequate application and stands out from the rest.
High-quality applications for all platforms, a nice download page for a shared file, very fast synchronization of a huge crowd of small files.
Of the minuses for me - the minimum tariff is $ 10 - 1TB, a bit too much. Long file upload in Android application. Google Drive
has one of the advantages - a tariff for $ 2 - 100GB, video playback from your disk is like from Youtube. Synchronization of a large number of files - loads the computer and takes 2.5 times longer than with DropBox. The download page of shared files is full print, it's hard to find the "Download" button.
Another interesting option is OneDrive, there is a cool function under Windows for files and folders, right in the context menu "Available only via the Internet" and "Available offline". That is, some of the files, even within the same folder, can be physically located on the disk, and some of the files will not take up disk space, they will be downloaded from the cloud when the file is opened. But the speed is not impressive, so I refused this option.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question