QT Widgets的实时变化?
Real Time Change of QT Widgets?
我正在尝试创建一个简单的 class 背诵应用程序,它会从学生列表中随机选择。
可以用,但是我要实时变化,所以有点悬念谁被pick了
您可以在下面的插图视频中看到控制台实时更新名称,但 QtWidget 不会:
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_()
有解决办法吗?
在time.sleep()
、
之后调用QApplication.processEvents()
def random_pick(self):
...
for x in range(0,10000):
...
sleep(counter)
QApplication.processEvents()
...
或者使用 QTimer 代替,它也避免了任意循环并且是完全非阻塞的。
class MainWindow(QMainWindow):
def __init__(self):
...
self.pick_btn = QPushButton("Pick")
self.pick_btn.setObjectName("Pick")
<b>self.pick_btn.clicked.connect(self.start_timer)
self.timer = QTimer(timeout=self.random_pick)
...</b>
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)
<b>self.timer.setInterval(self.counter * 1000)</b>
if time_elapse >= 5:
self.timer.stop()
return random_pick
我正在尝试创建一个简单的 class 背诵应用程序,它会从学生列表中随机选择。 可以用,但是我要实时变化,所以有点悬念谁被pick了
您可以在下面的插图视频中看到控制台实时更新名称,但 QtWidget 不会: 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_()
有解决办法吗?
在time.sleep()
、
QApplication.processEvents()
def random_pick(self):
...
for x in range(0,10000):
...
sleep(counter)
QApplication.processEvents()
...
或者使用 QTimer 代替,它也避免了任意循环并且是完全非阻塞的。
class MainWindow(QMainWindow):
def __init__(self):
...
self.pick_btn = QPushButton("Pick")
self.pick_btn.setObjectName("Pick")
<b>self.pick_btn.clicked.connect(self.start_timer)
self.timer = QTimer(timeout=self.random_pick)
...</b>
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)
<b>self.timer.setInterval(self.counter * 1000)</b>
if time_elapse >= 5:
self.timer.stop()
return random_pick