我下面的代码在Pi上运行,并且屏幕上的“滚动”按钮有效,可以滚动屏幕上的内容。然后,我将按下GPIO按钮的按钮附加到相同的Scroll方法上,并且当按下硬件按钮时代码运行时,直到将鼠标移到应更新的区域上,屏幕才会更新。
我尝试了各种方法来更新屏幕,但没有一个起作用:
self.IQM.dataChanged.emit(QtCore.QModelIndex(), QtCore.QModelIndex())
self.IQM.layoutChanged.emit()
self.update()
最小示例代码如下。非常感谢您的帮助。
非常感谢
凯文
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import QMainWindow, QWidget, QGridLayout
from PyQt5.QtWidgets import QTreeView, QApplication, qApp, QPushButton
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtCore import Qt, pyqtSlot
import sys
import RPi.GPIO as GPIO
class StartMarshall(QMainWindow):
def __init__(self):
super().__init__()
self.data = ['XXX' for _ in range(10)]
# Build Central Widget
self.widget = QWidget()
self.setCentralWidget(self.widget)
# build buttons
scrollButton = self.createButton(self.scroll, 'Scroll', 'Scroll action')
exitButton = self.createButton(qApp.quit, 'Exit', 'Exit action')
# Setup RPI GPIO Hardware Buttons
# Use Broadcom GPIO numbers (BCM)
GPIO.setmode(GPIO.BCM)
pinStartGate = 4
# Setup pinSG as an Input with a pull up resistor attached (ie pull down for press)
GPIO.setup(pinSG, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Call self.scroll on button press
GPIO.add_event_detect(pinSG, GPIO.FALLING, callback=self.scroll, bouncetime=300)
grid = QGridLayout()
grid.setSpacing(10)
# intialize view of data
self.IQ = IQ = QTreeView()
# Prepopulate View Models
self.IQM = self.prepModel(IQ)
self.fillModel(self.IQM, self.data[2:len(self.data)])
# include the widgets
grid.addWidget(IQ, 3, 1, -1, -1)
grid.addWidget(scrollButton, 5, 0)
grid.addWidget(exitButton, 7, 0)
self.widget.setLayout(grid)
# Show QMainWindow
self.show()
#self.showFullScreen()
#self.showMaximized()
def createButton(self, on_click, btn_txt='button title', btn_tip='this is a button hint'):
button = QPushButton(btn_txt, self)
button.setToolTip(btn_tip)
button.clicked.connect(on_click)
return button
def prepModel(self, widget):
# initialize a model
model = QStandardItemModel()
# remove indentation and headers
widget.setIndentation(0)
widget.setHeaderHidden(1)
# add (data) model to widget
widget.setModel(model)
return model
def fillModel(self, model, data):
# for refilling model data
for i, d in enumerate(data):
model.setItem(i, QStandardItem(d))
return
@pyqtSlot()
def scroll(self, event=None):
print("Scroll")
# when scroll button is clicked
if self.data[1:2] == '': # if second data is blank then no need to scroll
return
# remove the first element from data
self.data.pop(0)
# add the padded (blank) element from data
self.data.append('')
# show the full queue (-1 doesnt show last racer?)
self.fillModel(self.IQM, self.data[2:len(self.data)])
return
# Main
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = StartMarshall()
sys.exit(app.exec_())
答案 0 :(得分:0)
add_event_detect调用的回调在辅助线程上执行,在Qt中,禁止从另一个线程更新GUI。因此,诀窍是使用QTimer.singleShot(0, ...)
和functools.partial
来更新GUI:
from functools import partial
# ...
class StartMarshall(QMainWindow):
# ...
@pyqtSlot(QStandardItemModel, list)
def fillModel(self, model, data):
# for refilling model data
for i, d in enumerate(data):
model.setItem(i, QStandardItem(d))
return
def scroll(self, event=None):
print("Scroll")
# when scroll button is clicked
# if second data is blank then no need to scroll
if self.data[1:2] == "":
return
# remove the first element from data
self.data.pop(0)
# add the padded (blank) element from data
self.data.append("")
# show the full queue (-1 doesnt show last racer?)
wrapper = partial(self.fillModel, self.IQM, self.data[2:])
QtCore.QTimer.singleShot(0, wrapper)
return