我有一个PyQT GUI代码,它从旋转框获取用户输入(角度)并以指定的角度更新GUI上的罗盘对象。我想使用for-loop(0到360)从代码内部而不是spinbox更新指南针对象,两者之间有一些延迟,以进行类似时钟的运动。请提出一些实现方法。
当前代码:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
class CompassWidget(QWidget):
angleChanged = pyqtSignal(float)
def __init__(self, parent = None):
QWidget.__init__(self, parent)
self._angle = 0.0
self._margins = 10
self._pointText = {0: "N", 45: "NE", 90: "E", 135: "SE", 180: "S",
225: "SW", 270: "W", 315: "NW"}
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(event.rect(), self.palette().brush(QPalette.Window))
self.drawMarkings(painter)
self.drawNeedle(painter)
painter.end()
def drawMarkings(self, painter):
painter.save()
painter.translate(self.width()/2, self.height()/2)
scale = min((self.width() - self._margins)/120.0,
(self.height() - self._margins)/120.0)
painter.scale(scale, scale)
font = QFont(self.font())
font.setPixelSize(10)
metrics = QFontMetricsF(font)
painter.setFont(font)
painter.setPen(self.palette().color(QPalette.Shadow))
i = 0
while i < 360:
if i % 45 == 0:
painter.drawLine(0, -40, 0, -50)
painter.drawText(-metrics.width(self._pointText[i])/2.0, -52,self._pointText[i])
else:
painter.drawLine(0, -45, 0, -50)
painter.rotate(1)
i += 1
painter.restore()
def drawNeedle(self, painter):
painter.save()
painter.translate(self.width()/2, self.height()/2)
painter.rotate(self._angle)
scale = min((self.width() - self._margins)/120.0,
(self.height() - self._margins)/120.0)
painter.scale(scale, scale)
painter.setPen(QPen(Qt.NoPen))
painter.setBrush(self.palette().brush(QPalette.Shadow))
painter.drawPolygon(
QPolygon([QPoint(-10, 0), QPoint(0, -45), QPoint(10, 0),
QPoint(0, 45), QPoint(-10, 0)])
)
painter.setBrush(self.palette().brush(QPalette.Highlight))
painter.drawPolygon(
QPolygon([QPoint(-5, -25), QPoint(0, -45), QPoint(5, -25),
QPoint(0, -30), QPoint(-5, -25)])
)
painter.restore()
def sizeHint(self):
return QSize(600, 600)
def angle(self):
return self._angle
@pyqtSlot(float)
def setAngle(self, angle):
if angle != self._angle:
self._angle = angle
self.angleChanged.emit(angle)
self.update()
angle = pyqtProperty(float, angle, setAngle)
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if __name__ == "__main__":
app = QApplication(sys.argv)
window = QWidget()
compass = CompassWidget()
spinBox = QSpinBox()
spinBox.setRange(0, 359)
#compass.angleChanged.connect(compass.setAngle)
spinBox.valueChanged.connect(compass.setAngle)
layout = QVBoxLayout()
layout.addWidget(compass)
layout.addWidget(spinBox)
window.setLayout(layout)
window.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
QPropertyAnimation
类专为此目的而设计,非常易于使用。有一系列内置easing-curves可以帮助使动画看起来更自然。
以下是基于示例脚本的演示。 (请注意,您需要在旋转框中按Enter键以更改值):
Allocating common symbols
Common symbol size file
buddy_num 0x40 build/memory/page_alloc.c.o
buddy_map 0x40 build/memory/page_alloc.c.o
Discarded input sections
.comment 0x0000000000000000 0x4e build/kernel/main.c.o
.note.GNU-stack
0x0000000000000000 0x0 build/kernel/main.c.o
.eh_frame 0x0000000000000000 0x70 build/kernel/main.c.o
.comment 0x0000000000000000 0x4e build/memory/page_alloc.c.o
.note.GNU-stack
0x0000000000000000 0x0 build/memory/page_alloc.c.o
.eh_frame 0x0000000000000000 0xa8 build/memory/page_alloc.c.o
.comment 0x0000000000000000 0x4e build/memory/virt_alloc.c.o
.note.GNU-stack
0x0000000000000000 0x0 build/memory/virt_alloc.c.o
.comment 0x0000000000000000 0x4e build/library/bitmap.c.o
.note.GNU-stack
0x0000000000000000 0x0 build/library/bitmap.c.o
.eh_frame 0x0000000000000000 0x50 build/library/bitmap.c.o
.comment 0x0000000000000000 0x4e build/library/string.c.o
.note.GNU-stack
0x0000000000000000 0x0 build/library/string.c.o
.eh_frame 0x0000000000000000 0x150 build/library/string.c.o
Memory Configuration
Name Origin Length Attributes
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
/DISCARD/
*(.comment)
*(.note.GNU-stack)
*(.eh_frame)
*(.comment)
*(.note.GNU-stack)
*(.eh_frame)
0x0000000000100000 . = 0x100000
0x0000000000100000 kernel_load_addr = .
0x0000000000100000 text_start_addr = .
.text 0x0000000000100000 0x262f
0x0000000000100000 kernel_text_start = .
*(.boot)
.boot 0x0000000000100000 0x29 build/boot/boot.asm.o
*(.text*)
*fill* 0x0000000000100029 0x7 90
.text 0x0000000000100030 0x0 build/boot/boot.asm.o
.text 0x0000000000100030 0x14f build/boot/init.asm.o
0x0000000000100030 wheel_init
*fill* 0x000000000010017f 0x1 90
.text 0x0000000000100180 0x73c build/kernel/main.c.o
0x0000000000100180 raw_write
0x0000000000100210 read_info
0x00000000001005e0 wheel_main
*fill* 0x00000000001008bc 0x4 90
.text 0x00000000001008c0 0x974 build/memory/page_alloc.c.o
0x00000000001008c0 page_alloc_init
0x0000000000100cb0 find_free_pages
0x0000000000100ef0 alloc_pages
0x00000000001010c0 free_pages
.text 0x0000000000101234 0x0 build/memory/virt_alloc.c.o
*fill* 0x0000000000101234 0xc 90
.text 0x0000000000101240 0x2ff build/library/bitmap.c.o
0x0000000000101240 bitmap_set
0x00000000001013c0 bitmap_clear
*fill* 0x000000000010153f 0x1 90
.text 0x0000000000101540 0x10ef build/library/string.c.o
0x0000000000101540 strlen
0x0000000000101650 strcpy
0x00000000001016c0 strncpy
0x0000000000101770 memcpy
0x0000000000101960 memset
0x0000000000101b60 u32_to_str
0x0000000000101c90 u64_to_str
0x0000000000101dd0 i32_to_str
0x0000000000101e60 i64_to_str
0x0000000000101ef0 vsprintf
0x00000000001025d0 sprintf
0x000000000010262f kernel_text_end = .
0x000000000010262f kernel_text_start = .
*(.boot)
*(.text*)
0x000000000010262f kernel_text_end = .
.data 0x0000000000102630 0x174
0x0000000000102630 kernel_data_start = .
*(.rodata*)
.rodata 0x0000000000102630 0x8 build/kernel/main.c.o
.rodata.str1.1
0x0000000000102638 0x82 build/kernel/main.c.o
*fill* 0x00000000001026ba 0x6 00000000
.rodata 0x00000000001026c0 0xa5 build/library/string.c.o
*(.data*)
*fill* 0x0000000000102765 0x3 00000000
.data 0x0000000000102768 0x3a build/boot/init.asm.o
*fill* 0x00000000001027a2 0x2 00000000
.data 0x00000000001027a4 0x0 build/kernel/main.c.o
.data 0x00000000001027a4 0x0 build/memory/page_alloc.c.o
.data 0x00000000001027a4 0x0 build/memory/virt_alloc.c.o
.data 0x00000000001027a4 0x0 build/library/bitmap.c.o
.data 0x00000000001027a4 0x0 build/library/string.c.o
0x00000000001027a4 kernel_data_end = .
0x00000000001027a4 kernel_data_start = .
*(.rodata*)
*(.data*)
0x00000000001027a4 kernel_data_end = .
0x00000000001027a4 data_end_addr = .
.bss 0x0000000000103000 0x6000
0x0000000000103000 kernel_bss_start = .
*(COMMON)
COMMON 0x0000000000103000 0x80 build/memory/page_alloc.c.o
0x0000000000103000 buddy_num
0x0000000000103040 buddy_map
*(.bss)
*fill* 0x0000000000103080 0xf80 00000000
.bss 0x0000000000104000 0x5000 build/boot/init.asm.o
0x0000000000104000 kernel_stack
0x0000000000105000 pml4t
.bss 0x0000000000109000 0x0 build/kernel/main.c.o
.bss 0x0000000000109000 0x0 build/memory/page_alloc.c.o
.bss 0x0000000000109000 0x0 build/memory/virt_alloc.c.o
.bss 0x0000000000109000 0x0 build/library/bitmap.c.o
.bss 0x0000000000109000 0x0 build/library/string.c.o
0x0000000000109000 kernel_bss_end = .
0x0000000000109000 kernel_bss_start = .
*(COMMON)
*(.bss)
0x0000000000109000 kernel_bss_end = .
0x0000000000109000 bss_end_addr = .
0x0000000000109000 kernel_end = .
LOAD build/boot/boot.asm.o
LOAD build/boot/init.asm.o
LOAD build/kernel/main.c.o
LOAD build/memory/page_alloc.c.o
LOAD build/memory/virt_alloc.c.o
LOAD build/library/bitmap.c.o
LOAD build/library/string.c.o
LOAD link.lds
0x0000000000100000 . = 0x100000
0x0000000000100000 kernel_load_addr = .
0x0000000000100000 text_start_addr = .
0x0000000000100000 data_end_addr = .
0x0000000000100000 bss_end_addr = .
0x0000000000100000 kernel_end = .
OUTPUT(build/kernel.bin binary)
答案 1 :(得分:0)
使用Python PySide and Progress Bar Threading中的示例
import sys
import time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Worker(QThread):
updateAngle = pyqtSignal(float)
def __init__(self):
QThread.__init__(self)
def run(self):
for i in range(360):
self.updateAngle.emit(i)
time.sleep(0.2)
class CompassWidget(QWidget):
angleChanged = pyqtSignal(float)
def __init__(self, parent = None):
QWidget.__init__(self, parent)
self._angle = 0.0
self._margins = 10
self._pointText = {0: "N", 45: "NE", 90: "E", 135: "SE", 180: "S",
225: "SW", 270: "W", 315: "NW"}
self._worker = Worker()
self._worker.updateAngle.connect(self.setAngle)
self._worker.start()
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(event.rect(), self.palette().brush(QPalette.Window))
self.drawMarkings(painter)
self.drawNeedle(painter)
painter.end()
def drawMarkings(self, painter):
painter.save()
painter.translate(self.width()/2, self.height()/2)
scale = min((self.width() - self._margins)/120.0,
(self.height() - self._margins)/120.0)
painter.scale(scale, scale)
font = QFont(self.font())
font.setPixelSize(10)
metrics = QFontMetricsF(font)
painter.setFont(font)
painter.setPen(self.palette().color(QPalette.Shadow))
i = 0
while i < 360:
if i % 45 == 0:
painter.drawLine(0, -40, 0, -50)
painter.drawText(-metrics.width(self._pointText[i])/2.0, -52,self._pointText[i])
else:
painter.drawLine(0, -45, 0, -50)
painter.rotate(1)
i += 1
painter.restore()
def drawNeedle(self, painter):
painter.save()
painter.translate(self.width()/2, self.height()/2)
painter.rotate(self._angle)
scale = min((self.width() - self._margins)/120.0,
(self.height() - self._margins)/120.0)
painter.scale(scale, scale)
painter.setPen(QPen(Qt.NoPen))
painter.setBrush(self.palette().brush(QPalette.Shadow))
painter.drawPolygon(
QPolygon([QPoint(-10, 0), QPoint(0, -45), QPoint(10, 0),
QPoint(0, 45), QPoint(-10, 0)])
)
painter.setBrush(self.palette().brush(QPalette.Highlight))
painter.drawPolygon(
QPolygon([QPoint(-5, -25), QPoint(0, -45), QPoint(5, -25),
QPoint(0, -30), QPoint(-5, -25)])
)
painter.restore()
def sizeHint(self):
return QSize(600, 600)
def angle(self):
return self._angle
@pyqtSlot(float)
def setAngle(self, angle):
if angle != self._angle:
self._angle = angle
self.angleChanged.emit(angle)
self.update()
angle = pyqtProperty(float, angle, setAngle)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = QWidget()
compass = CompassWidget()
spinBox = QSpinBox()
spinBox.setRange(0, 359)
spinBox.valueChanged.connect(compass.setAngle)
layout = QVBoxLayout()
layout.addWidget(compass)
layout.addWidget(spinBox)
window.setLayout(layout)
window.show()
sys.exit(app.exec_())
简而言之,如果您使用Qt,则应使用QThread
而不是本机python线程。
答案 2 :(得分:0)
如何使用QTimer?将其timeout
信号连接到一些增加计数器并告诉指南针小部件更新的方法。