I'm trying to create a simple class recitation app where it randomly picks from the list of students.
It works, but I want it to change in real time, so there's a bit of suspense who is being picked.
You can see in the illustration video below that the console updates the names in real time but the QtWidget does not:
https://dl.dropboxusercontent.com/s/rwcbhhj58tevshl/py003_pyqt_real_time_update_widget.mp4?dl=0
import sys
import os
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QApplication, QMainWindow, QSpinBox, QWidget, QPushButton, QTextEdit, QVBoxLayout, QHBoxLayout, QLineEdit, QLabel
from PySide2.QtGui import QPixmap
from time import sleep, perf_counter
import time
import random
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Class Recitation")
# Widget
root_img_path = 'img'
self.image_list = []
for root, dirs, files in os.walk(root_img_path):
for f in files:
img_path = os.path.join(root_img_path, f)
first_name = f.split('_')[0]
last_name = f.split('_')[1]
self.image_list.append( (img_path, first_name + " " + last_name ) )
# creating label
self.label = QLabel(self)
# loading image
#self.pixmap = QPixmap('img/Eijirou_Kirishima_Portrait.png')
self.pixmap = QPixmap(self.image_list[0][0])
# adding image to label
self.label.setPixmap(self.pixmap)
self.name_label = QLabel()
self.name_label.setText(self.image_list[0][1])
self.pick_btn = QPushButton("Pick")
self.pick_btn.setObjectName("Pick")
self.pick_btn.clicked.connect(self.random_pick)
# Layout Creations
hbox = QHBoxLayout()
# hbox.addWidget(self.search_button)
# hbox.addWidget(self.search_bar)
vbox = QVBoxLayout()
vbox.addWidget(self.label)
vbox.addWidget(self.name_label)
vbox.addWidget(self.pick_btn)
# vbox.addWidget(self.result_text_edit)
layout = QVBoxLayout()
layout.addLayout(hbox)
layout.addLayout(vbox)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def random_pick(self):
choice_list = self.image_list
time_started = time.perf_counter()
counter = 0
for x in range(0,10000):
random_pick = random.choice(choice_list)
self.name_label.setText(random_pick[1])
self.label.setPixmap(random_pick[0])
print (random_pick[1])
sleep(counter)
current_time = time.perf_counter()
time_elapse = current_time - time_started
counter += 0.0001 * (2**4)
if time_elapse >= 5:
break
return random_pick
def change_name(self):
self.name_label.setText("Name Changed")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Is there a way around this?
Either call QApplication.processEvents() after time.sleep(),
def random_pick(self):
...
for x in range(0,10000):
...
sleep(counter)
QApplication.processEvents()
...
or use QTimer instead, which also avoids the arbitrary loop and is entirely non-blocking.
class MainWindow(QMainWindow):
def __init__(self):
...
self.pick_btn = QPushButton("Pick")
self.pick_btn.setObjectName("Pick")
self.pick_btn.clicked.connect(self.start_timer)
self.timer = QTimer(timeout=self.random_pick)
...
def start_timer(self):
self.time_started = time.perf_counter()
self.counter = 0
self.timer.start(0)
def random_pick(self):
choice_list = self.image_list
random_pick = random.choice(choice_list)
self.name_label.setText(random_pick[1])
self.label.setPixmap(random_pick[0])
current_time = time.perf_counter()
time_elapse = current_time - self.time_started
self.counter += 0.0001 * (2**4)
self.timer.setInterval(self.counter * 1000)
if time_elapse >= 5:
self.timer.stop()
return random_pick
Related
I am writing a little program, but the buttons don't work
as I expected.
I wish the text to change state when I click on the button of that text.
Here is the code to test it:
from sys import exit
from sys import argv
from PyQt6.QtWidgets import QApplication, QHBoxLayout, QPushButton, QVBoxLayout, QLabel, QWidget, QLineEdit
class MainWindow(QWidget):
def __init__(self, parent=None) -> None:
super().__init__(parent)
self.screenWidth = 1920
self.screenHeight = 1080
self.windowWidth = 1000
self.windowHeight = 800
self.setWindowTitle("test 19")
self.setGeometry((self.screenWidth - self.windowWidth) // 2, (self.screenHeight - self.windowHeight) // 2, self.windowWidth, self.windowHeight)
self.initUi()
def initUi(self) -> None:
mainLayout = QVBoxLayout()
headLayout = QHBoxLayout()
nameLabel = QLabel("Name")
headLayout.addWidget(nameLabel)
mainLayout.addItem(headLayout)
row1 = Row("google.com")
mainLayout.addItem(row1.returnValues())
row2 = Row("yahoo.com")
mainLayout.addItem(row2.returnValues())
for i in range(20):
rowi = Row(f"{i}")
mainLayout.addItem(rowi.returnValues())
self.setLayout(mainLayout)
class Row():
def __init__(self, name) -> None:
super().__init__()
self.rowLayout = QHBoxLayout()
self.nameLineEdit = QLineEdit(f"{name}")
self.nameLineEdit.setDisabled(True)
self.rowLayout.addWidget(self.nameLineEdit)
self.hiddenOrShowButton = QPushButton("")
self.hiddenOrShowButton.clicked.connect(self.hiddenOrShow)
self.rowLayout.addWidget(self.hiddenOrShowButton)
def returnValues(self) -> QHBoxLayout:
return self.rowLayout
def hiddenOrShow(self) -> None:
if self.nameLineEdit.echoMode() == QLineEdit.EchoMode.Password:
self.nameLineEdit.setEchoMode(QLineEdit.EchoMode.Normal)
else:
self.nameLineEdit.setEchoMode(QLineEdit.EchoMode.Password)
if __name__ == "__main__":
app = QApplication(argv)
window = MainWindow()
window.show()
exit(app.exec())
I expect the text to change state when I click on the button of that text.
Your best bet is to subclass QHBoxLayout, as suggested by musicamante in the comments, and your Row class isn't that far off from doing just that.
The only changes that really need to be made are to add in the subclass reference in your Row to Row(QHBoxLayout), then would want to remove the self.rowLayout line because the Row class would become the layout. and you would change all the references to it to just self instead of self.rowLayout.
For example:
from sys import exit
from sys import argv
from PyQt6.QtWidgets import QApplication, QHBoxLayout, QPushButton, QVBoxLayout, QLabel, QWidget, QLineEdit
class MainWindow(QWidget):
def __init__(self, parent=None) -> None:
super().__init__(parent)
self.screenWidth = 1920
self.screenHeight = 1080
self.windowWidth = 1000
self.windowHeight = 800
self.setWindowTitle("test 19")
self.setGeometry((self.screenWidth - self.windowWidth) // 2, (self.screenHeight - self.windowHeight) // 2, self.windowWidth, self.windowHeight)
self.initUi()
def initUi(self) -> None:
mainLayout = QVBoxLayout()
headLayout = QHBoxLayout()
nameLabel = QLabel("Name")
headLayout.addWidget(nameLabel)
mainLayout.addLayout(headLayout)
row1 = Row("google.com") # the row now is the layout
mainLayout.addLayout(row1) # so you add it directly to the main layout
row2 = Row("yahoo.com")
mainLayout.addLayout(row2) # use addLayout instead of addItem
for i in range(20):
rowi = Row(f"{i}")
mainLayout.addLayout(rowi)
self.setLayout(mainLayout)
class Row(QHBoxLayout): # use subclass declaration
def __init__(self, name):
super().__init__()
self.nameLineEdit = QLineEdit(f"{name}")
self.nameLineEdit.setDisabled(True)
self.addWidget(self.nameLineEdit) # add the widget to self
self.hiddenOrShowButton = QPushButton("")
self.hiddenOrShowButton.clicked.connect(self.hiddenOrShow)
self.addWidget(self.hiddenOrShowButton) # same thing here
# the returnValues method can be removed.
def hiddenOrShow(self) -> None:
if self.nameLineEdit.echoMode() == QLineEdit.EchoMode.Password:
self.nameLineEdit.setEchoMode(QLineEdit.EchoMode.Normal)
else:
self.nameLineEdit.setEchoMode(QLineEdit.EchoMode.Password)
if __name__ == "__main__":
app = QApplication(argv)
window = MainWindow()
window.show()
exit(app.exec())
This question already has answers here:
In PyQt, what is the best way to share data between the main window and a thread
(1 answer)
Background thread with QThread in PyQt
(7 answers)
Example of the right way to use QThread in PyQt?
(3 answers)
Closed 4 months ago.
I'm trying to make Typing speed test app in Pyqt, but it recently started crashing when I was inside QLineEdit. Sometimes it crashed instantly after I tried typing, sometimes only after tens of character were typed.
My code:
from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QStackedWidget, QPushButton, QSizePolicy, QLabel, QLineEdit, QHBoxLayout, QVBoxLayout
from PyQt5.QtCore import *
import sys
import time
import random
import threading
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle("Typing Speed Test App")
self.setMinimumSize(1280,720)
global stacked
stacked = QStackedWidget(self)
self.setCentralWidget(stacked)
stacked.addWidget(Menu())
stacked.addWidget(TS_Test())
stacked.addWidget(Statistics())
stacked.setCurrentIndex(1) # test only
class Menu(QWidget):
def __init__(self):
QWidget.__init__(self)
self.frameWidth = self.frameSize().width()
self.frameHeight = self.frameSize().height()
self.initUI()
def initUI(self):
self.button_test = QPushButton(self)
self.button_graph = QPushButton(self)
self.button_test.setFixedWidth(50)
self.button_test.clicked.connect(lambda: stacked.setCurrentIndex(1))
self.button_graph.clicked.connect(lambda: stacked.setCurrentIndex(2))
self.button_graph.clicked.connect(lambda: print(self.frameSize().width()))
self.button_test.move(self.frameSize().width()*50//100-50,200)
self.button_graph.move(200,230)
class TS_Test(QWidget):
def __init__(self):
QWidget.__init__(self)
f = open('paragraphs.txt').read()
self.sentences = f.split('BREAK\n')
self.sentence = random.choice(self.sentences)
self.sentence = self.sentence.strip('\n')
self.word = self.sentence.split()
self.setStyleSheet("QLabel{font-size: 15px;}")
self.initUI()
self.start_thread()
def initUI(self):
self.button_back = QPushButton(self)
self.button_back.clicked.connect(lambda: stacked.setCurrentIndex(0))
self.button_back.move(30,50)
self.lineEdit = QLineEdit()
self.label = QLabel()
self.accuracy_label = QLabel()
self.wpm_label = QLabel()
self.first_letter = self.sentence[0]
self.layout = QVBoxLayout(self)
self.layout.addWidget(self.label)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.accuracy_label)
self.layout.addWidget(self.wpm_label)
self.label.setText(self.sentence)
self.layout.setContentsMargins(250,250,250,300)
self.setLayout(self.layout)
def start_thread(self):
self.t_start=threading.Thread(target=self.start)
self.t_start.start()
def start(self):
while True:
if len(self.lineEdit.text()) > 0:
if self.lineEdit.text()[0] == self.first_letter:
self.time_thread()
break
def time_thread(self):
print('start')
timer_start = time.perf_counter()
self.correct_char = 0
while True:
if (len(self.lineEdit.text()) == len(self.sentence)) and (self.lineEdit.text().split()[-1] == self.word[-1]):
self.written_word = self.lineEdit.text().split(' ')
timer_stop = time.perf_counter()
timer = timer_stop - timer_start
self.wpm = len(self.written_word) / timer * 60
for i in range(len(self.sentence)):
if self.lineEdit.text()[i] == self.sentence[i]:
self.correct_char += 1
self.accuracy = self.correct_char / len(self.sentence) * 100
print(f"Accuracy = {self.correct_char / len(self.sentence) * 100}")
print(f'WPM: {self.wpm:0.3f}')
self.accuracy_label.setText(f'Accuracy = {self.accuracy}%')
self.wpm_label.setText(f'WPM: {self.wpm:0.3f}')
break
class Statistics(QWidget):
def __init__(self):
QWidget.__init__(self)
self.initUI()
def initUI(self):
self.button_back = QPushButton(self)
self.button_back.clicked.connect(lambda: stacked.setCurrentIndex(0))
self.button_back.move(400,300)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainwin = MainWindow()
mainwin.show()
sys.exit(app.exec_())
I've tried doing try and except so that it can print me traceback error, but even that didn't print anything. I read somewhere that it might be because I'm using library threading instead of QThread, but I have no idea if that has something to do with it.
EDIT:
Content in paragraphs.txt:
This line serves as test.
BREAK
Sentence number one.
BREAK
Sentence number two.
BREAK
Line number three.
my function won't work when the slider value changed i don't know why ? it's my first time using PyQt5.
from PIL.ImageQt import Image, ImageQt
from PIL import ImageEnhance
from PyQt5.QtWidgets import (QApplication, QDialog, QGridLayout,
QLabel, QPushButton, QGroupBox,
QSlider, QVBoxLayout, QFileDialog)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QIcon
class MainWindow(QDialog):
def __init__(self):
super(MainWindow,self).__init__()
self.originalPalette = QApplication.palette()
# self.setAcceptDrops(True)
self.createTopGroupBox()
self.createBottomGroupBox()
# self.color("blue")
mainLayout = QGridLayout()
mainLayout.addWidget(self.topGroupBox, 0, 0)
mainLayout.addWidget(self.bottomGroupBox, 1, 0)
#mainLayout.setRowStretch(1, 1)
#mainLayout.setRowStretch(2, 1)
#mainLayout.setColumnStretch(0, 1)
#mainLayout.setColumnStretch(1, 1)
self.setLayout(mainLayout)
self.setWindowTitle("Photo Editor")
self.resize(800, 800)
def createTopGroupBox(self):
self.topGroupBox = QGroupBox()
openImgButton = QPushButton("Open Image")
openImgButton.clicked.connect(self.getImage)
self.label = QLabel("Your Photo")
layout = QVBoxLayout()
layout.addWidget(openImgButton)
layout.addWidget(self.label)
layout.addStretch(1)
self.topGroupBox.setLayout(layout)
def getImage(self):
global fname
fname = QFileDialog.getOpenFileName(self, 'Open file',
'c:\ ', "Image files (*.jpeg *.jpg *.gif *.bmp *.png))")
imagePath = fname[0]
#pixmap = QPixmap(imagePath)
self.image = Image.open(imagePath)
self.qimage = ImageQt(self.image)
self.label.setPixmap(QPixmap.fromImage(self.qimage))
self.resize(self.qimage.width(), self.qimage.height())
def createBottomGroupBox(self):
self.bottomGroupBox = QGroupBox()
self.sliderBrightness = QSlider(Qt.Horizontal, self)
brightnessLabel = QLabel("Brightness:")
brightnessLabel.setBuddy(self.sliderBrightness)
self.sliderBrightness.setTickPosition(QSlider.TicksBelow)
self.sliderBrightness.setTickInterval(1)
self.sliderBrightness.setValue(100)
self.sliderBrightness.setMinimum(0)
self.sliderBrightness.setMaximum(200)
self.brightnessValueLabel = QLabel("1")
self.sliderContrast = QSlider(Qt.Horizontal, self)
contrastLabel = QLabel("Contrast:")
contrastLabel.setBuddy(contrastLabel)
self.sliderContrast.setValue(1)
self.sliderContrast.setMinimum(0)
self.sliderContrast.setMaximum(2)
self.contrastValueLabel = QLabel("1")
sliderSharpness = QSlider(Qt.Horizontal, self)
sharpnessLabel = QLabel("Sharpness:")
sharpnessLabel.setBuddy(sharpnessLabel)
sliderSharpness.setValue(1)
sliderSharpness.setMinimum(0)
sliderSharpness.setMaximum(2)
self.sharpnessValueLabel = QLabel("1")
savePushButton = QPushButton("Save")
savePushButton.clicked.connect(self.saveImage("image.png", "PNG"))
self.sliderBrightness.valueChanged.connect(self.valueChangeBrightness)
self.sliderContrast.valueChanged.connect(self.valueChangeContrast)
sliderSharpness.valueChanged.connect(self.valueChangeSharpness)
layout = QVBoxLayout()
layout.addWidget(brightnessLabel)
layout.addWidget(self.sliderBrightness, 0)
layout.addWidget(self.brightnessValueLabel)
layout.addWidget(contrastLabel)
layout.addWidget(self.sliderContrast, 1)
layout.addWidget(sharpnessLabel)
layout.addWidget(sliderSharpness, 2)
layout.addWidget(savePushButton, 3)
self.bottomGroupBox.setLayout(layout)
def saveImage(self, fileName, fileFormat):
self.editImage.save(fileName, fileFormat)
def valueChangeBrightness(self, sliderValue):
factor = float(sliderValue)/100
enhancer_object = ImageEnhance.Brightness(self.image)
self.editImage = enhancer_object.enhance(factor)
self.brightnessValueLabel.setText(str(self.sliderBrightness.value()))
def valueChangeContrast(self, factor):
enhancer_object = ImageEnhance.Contrast(self.image)
enhancer_object.enhance(factor)
def valueChangeSharpness(self, factor):
enhancer_object = ImageEnhance.Sharpness(self.image)
enhancer_object.enhance(factor)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
The main problem in the OP code is that it has not updated the image shown. For example, if the docs is reviewed, it is understood that the enhance method returns the modified image but is neither saved nor displayed.
On the other hand the application of the changes must be in cascade (one behind the other).
There are also errors such as not verifying that the filename is an empty string, in addition that the clicked signal is connected to a shutdown, not to which an evaluated function returns.
Considering the above, the solution is:
from PIL.ImageQt import Image, ImageQt
from PIL import ImageEnhance
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
QApplication,
QDialog,
QGridLayout,
QLabel,
QPushButton,
QGroupBox,
QSlider,
QVBoxLayout,
QFileDialog,
)
class MainWindow(QDialog):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.createTopGroupBox()
self.createBottomGroupBox()
mainLayout = QGridLayout(self)
mainLayout.addWidget(self.topGroupBox, 0, 0)
mainLayout.addWidget(self.bottomGroupBox, 1, 0)
self.setWindowTitle("Photo Editor")
self.resize(800, 800)
self.input_image = None
self.output_image = None
def createTopGroupBox(self):
self.topGroupBox = QGroupBox()
openImgButton = QPushButton("Open Image")
openImgButton.clicked.connect(self.getImage)
self.label = QLabel("Your Photo")
layout = QVBoxLayout()
layout.addWidget(openImgButton)
layout.addWidget(self.label)
layout.addStretch(1)
self.topGroupBox.setLayout(layout)
def getImage(self):
fname, _ = QFileDialog.getOpenFileName(
self, "Open file", "", "Image files (*.jpeg *.jpg *.gif *.bmp *.png)"
)
if fname:
self.input_image = Image.open(fname)
self.show_image(self.input_image)
def show_image(self, image):
qimage = ImageQt(image)
self.label.setPixmap(QPixmap.fromImage(qimage))
def createBottomGroupBox(self):
self.bottomGroupBox = QGroupBox()
self.sliderBrightness = QSlider(
Qt.Horizontal,
tickPosition=QSlider.TicksBelow,
tickInterval=1,
value=100,
minimum=0,
maximum=200,
)
brightnessLabel = QLabel("Brightness:")
brightnessLabel.setBuddy(self.sliderBrightness)
self.brightnessValueLabel = QLabel()
self.brightnessValueLabel.setNum(self.sliderBrightness.value())
self.sliderContrast = QSlider(Qt.Horizontal, value=1, minimum=0, maximum=2)
contrastLabel = QLabel("Contrast:")
contrastLabel.setBuddy(self.sliderContrast)
self.contrastValueLabel = QLabel()
self.contrastValueLabel.setNum(self.sliderContrast.value())
self.sliderSharpness = QSlider(Qt.Horizontal, value=1, minimum=0, maximum=2)
sharpnessLabel = QLabel("Sharpness:")
sharpnessLabel.setBuddy(self.sliderSharpness)
self.sharpnessValueLabel = QLabel()
self.sharpnessValueLabel.setNum(self.sliderSharpness.value())
savePushButton = QPushButton("Save")
savePushButton.clicked.connect(lambda: self.saveImage("image.png", "PNG"))
self.sliderBrightness.valueChanged.connect(self.update_image)
self.sliderContrast.valueChanged.connect(self.update_image)
self.sliderSharpness.valueChanged.connect(self.update_image)
layout = QVBoxLayout()
layout.addWidget(brightnessLabel)
layout.addWidget(self.sliderBrightness)
layout.addWidget(self.brightnessValueLabel)
layout.addWidget(contrastLabel)
layout.addWidget(self.sliderContrast)
layout.addWidget(self.contrastValueLabel)
layout.addWidget(sharpnessLabel)
layout.addWidget(self.sliderSharpness)
layout.addWidget(self.sharpnessValueLabel)
layout.addWidget(savePushButton)
self.bottomGroupBox.setLayout(layout)
def saveImage(self, fileName, fileFormat):
if self.output_image is not None:
self.output_image.save(fileName, fileFormat)
def update_image(self):
if self.input_image is not None:
factor_brightness = self.sliderBrightness.value() / 100.0
factor_contrast = self.sliderContrast.value()
factor_sharpness = self.sliderSharpness.value()
enhancer_object = ImageEnhance.Brightness(self.input_image)
image = enhancer_object.enhance(factor_brightness)
enhancer_object = ImageEnhance.Contrast(image)
image = enhancer_object.enhance(factor_contrast)
enhancer_object = ImageEnhance.Sharpness(image)
self.output_image = enhancer_object.enhance(factor_sharpness)
self.show_image(self.output_image)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
this is my code, when i run it, it doesnt act like a clock. all it does it return a string. but what i wanted was the time moving by the seconds. help will be appreciated thank you
def DateTime(self):
dateandtime = QDialog()
dateandtime.setWindowTitle("Date and Time")
hbox = QHBoxLayout()
datetime = QDateTime.currentDateTime()
show = datetime.toString(Qt.DefaultLocaleLongDate)
label = QLabel(show)
label.setFont(QtGui.QFont("Arial", 10))
hbox.addWidget(label)
dateandtime.setLayout(hbox)
There should be a more elegant way, but find an example with a timer:
from PyQt5.QtWidgets import QDialog, QHBoxLayout, QLabel, QApplication
from PyQt5.QtCore import QDateTime, Qt, QTimer
from PyQt5 import QtGui
import sys
class Dialog(QDialog):
def __init__(self):
QDialog.__init__(self)
datetime = QDateTime.currentDateTime()
show = datetime.toString(Qt.DefaultLocaleLongDate)
self.label = QLabel(show)
self.DateTime()
def DateTime(self):
# dateandtime = QDialog()
self.setWindowTitle("Date and Time")
hbox = QHBoxLayout()
self.label.setFont(QtGui.QFont("Arial", 10))
hbox.addWidget(self.label)
self.setLayout(hbox)
def tick(self):
datetime = QDateTime.currentDateTime().toString(Qt.DefaultLocaleLongDate)
self.label.setText(datetime)
app = QApplication(sys.argv)
dialog = Dialog()
dialog.show()
timer = QTimer()
timer.timeout.connect(dialog.tick)
timer.start(1000)
app.exec_()
See my code and tell me how do I set progress bar to the -dollar()- function and progress bar start with doing the function and finished with it. see my code at the continue:
from PyQt5.QtWidgets import (QWidget,QApplication,QTextEdit,
QInputDialog,QPushButton,QVBoxLayout,QProgressBar)
import sys
class Tbx(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.vbox = QVBoxLayout()
self.btn = QPushButton('ClickMe',self)
self.btn.clicked.connect(self.dollar)
self.te = QTextEdit(self)
self.prgb = QProgressBar(self)#How to set this to doing something?
self.vbox.addWidget(self.te)
self.vbox.addWidget(self.btn)
self.vbox.addWidget(self.prgb)
self.setLayout(self.vbox)
self.setGeometry(300,300,400,250)
self.setWindowTitle('Application')
self.show()
def dollar(self):#Like doing this set progress bar to this
text_1_int , ok = QInputDialog.getInt(self,'HowMany?','Enter How Many dollar do you want ?')
if not ok:
return
current_lines = self.te.toPlainText().split('\n')
new_lines = list()
for dollar_counter in range(1,text_1_int+1):
word = '$'*dollar_counter
new_lines += [word + text for text in current_lines]
self.te.setPlainText('\n'.join(new_lines))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Tbx()
sys.exit(app.exec_())
You can set the maximum value of the progress control to the value entered in your input window and then simply use setValue to increase the progress bar, however, this will block the UI for very large calculations, so you might want to also move your method to a new thread and report progress to the UI using a signal, here is the full example:
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import (QWidget, QApplication, QTextEdit, QInputDialog, QPushButton, QVBoxLayout, QProgressBar)
import sys
class DollarCalculation(QThread):
reportProgress = pyqtSignal(int, list)
calculationFinished = pyqtSignal()
def __init__(self, numDollars, currentLines):
super().__init__()
self.numDollars = numDollars
self.currentLines = currentLines
def run(self) -> None:
for dollar_counter in range(1, self.numDollars + 1):
word = '$' * dollar_counter
self.reportProgress.emit(dollar_counter + 1, [word + text for text in self.currentLines])
self.calculationFinished.emit()
class Tbx(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.dollarCalculation = None
def initUI(self):
self.vbox = QVBoxLayout()
self.btn = QPushButton('ClickMe', self)
self.btn.clicked.connect(self.dollar)
self.te = QTextEdit(self)
self.prgb = QProgressBar(self)
self.vbox.addWidget(self.te)
self.vbox.addWidget(self.btn)
self.vbox.addWidget(self.prgb)
self.setLayout(self.vbox)
self.setGeometry(300, 300, 400, 250)
self.setWindowTitle('Application')
def dollar(self):
text_1_int, ok = QInputDialog.getInt(self, 'HowMany?', 'Enter How Many dollar do you want ?')
if not ok:
return
self.btn.setEnabled(False)
self.prgb.setMaximum(text_1_int + 1)
self.dollarCalculation = DollarCalculation(text_1_int, self.te.toPlainText().split('\n'))
self.dollarCalculation.reportProgress.connect(self.progress)
self.dollarCalculation.calculationFinished.connect(self.calculationFinished)
self.dollarCalculation.start()
def progress(self, value, newLines):
self.te.append('\n'.join(newLines))
self.prgb.setValue(value)
def calculationFinished(self):
self.btn.setEnabled(True)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Tbx()
ex.show()
sys.exit(app.exec_())