Нужен аналог PyQt QProgressBar
Я пишу приложение, которое чем-то похоже на discord authy и меня интересует та уползающая шкала вверху экрана.
Я пытался сделать её, используя QProgressBar от PyQt5, но когда приложение запускается, QProgressBar не даёт другим процессам выполняться.
Есть ли способ чем-нибудь его заменить? Желательно на PyQt5.
main.py:
import random
import time
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QWidget, QApplication, QLabel,
QVBoxLayout, QProgressBar, QPushButton
import pyperclip
def codegen():
letters = "abcdefghijklmnopqrstuvwxyz"
code = ""
for i in range(10):
number = random.randint(0, 9)
code += str(number)
code += ':'
for i in range(15):
ln = random.randint(0, 1)
if ln == 0:
ud = random.randint(0, 1)
letter = letters[random.randint(0, 25)]
if ud == 0:
letter = letter.upper()
code += letter
if ln == 1:
number = random.randint(0, 9)
code += str(number)
return code
def codecopy():
pyperclip.copy(w.title.text())
class Window(QWidget):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.pbar = QProgressBar()
self.title = QLabel()
self.copy = QPushButton('скопировать')
layout = QVBoxLayout(self)
layout.addWidget(self.title)
layout.addWidget(self.pbar)
layout.addWidget(self.copy)
QTimer.singleShot(3000, self.start)
self.copy.clicked.connect(codecopy)
def decrease(self):
for i in range(101):
time.sleep(0.05)
self.pbar.setValue(100 - i)
self.refresh()
def refresh(self):
if self.pbar.value() <= 0:
self.pbar.setValue(100)
self.title.setText(codegen())
self.decrease()
def start(self):
self.pbar.setValue(100)
self.title.setText(codegen())
self.decrease()
codecopy()
app = QApplication([])
w = Window()
w.show()
app.exec_()
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Нельзя использовать time.sleep(...) в основном потоке, это замораживает интерфейс.
Я не совсем понимаю когда вы собираетесь заканчивать цикл.
Для решения вашей задачи, вам нужен дополнительный поток и выглядит это может примерно так:
import random
#import time
from PyQt5.QtCore import Qt, QTimer, QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QApplication, QLabel, \
QVBoxLayout, QProgressBar, QPushButton, QMessageBox
import pyperclip
def codegen():
letters = "abcdefghijklmnopqrstuvwxyz"
code = ""
for i in range(10):
number = random.randint(0, 9)
code += str(number)
code += ':'
for i in range(15):
letter = '' # +
ln = random.randint(0, 1)
if ln == 0:
ud = random.randint(0, 1)
letter = letters[random.randint(0, 25)]
if ud == 0:
letter = letter.upper()
code += letter
if ln == 1:
number = random.randint(0, 9)
code += str(number)
return code
def codecopy():
pyperclip.copy(w.title.text())
QMessageBox.information(None, "Инфо", "title скопированы в буфер обмена!") #
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
class Worker(QThread):
progressChanged = pyqtSignal(int)
def run(self):
print(f'def run(self):') #
# def decrease(self):
for i in range(101):
self.msleep(50)
# self.pbar.setValue(100 - i)
self.progressChanged.emit(100 - i)
# self.refresh()
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class Window(QWidget):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.pbar = QProgressBar()
self.title = QLabel()
self.button_copy = QPushButton('скопировать')
layout = QVBoxLayout(self)
layout.addWidget(self.title)
layout.addWidget(self.pbar)
layout.addWidget(self.button_copy)
QTimer.singleShot(3000, self.start)
self.button_copy.clicked.connect(codecopy)
self.worker = Worker() # +++
self.worker.progressChanged.connect(self.updateProgress) # +++
def updateProgress(self, v): # +++
self.pbar.setValue(v)
self.refresh()
def refresh(self):
if self.pbar.value() <= 0:
self.pbar.setValue(100)
self.title.setText(codegen())
# self.decrease()
self.worker.start()
def start(self):
self.pbar.setValue(100)
_codegen = codegen()
print(f'_codegen = {_codegen}') #
self.title.setText(_codegen)
self.worker.start() # +++
# ? self.decrease()
codecopy()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
