我想通过读取文本文件值来旋转和翻译关于原点的线,并且它正在工作,但是它给了我最后一个和最后一个输出。我无法将其视为动画。 self.update()可能存在一些问题。文件名是无人机飞行阅读的日志文件。
{{1}}
提前致谢。
答案 0 :(得分:0)
我在tkinter中尝试了它并且它的工作正确。这是代码。
from tkinter import *
from tkinter import ttk
import xlrd
import time
import math
def read_file(lineno):
with open('d:\detect\log_file\Attitude_data_Manual_1232018_1215.txt','r',) as f :
lines = f.readlines()[4:]
for s in lines:
a = s.split()
#print (len(a))
if(len(a)!=14):
print("point reached")
lineno += 1
continue
pitch.append(float(a[4]))
roll.append(float(a[6]))
lineno += 1
# print(lineno)
return lineno
def counterrotate(origin,point1,roll):
ox,oy = origin
px,py = point1
angle=math.radians(roll)
#counterclockwise
qx= ox+ math.cos(angle)*(px-ox)-math.sin(angle)*(py-oy)
qy= oy+ math.sin(angle)*(px-ox)+math.cos(angle)*(py-oy)
return qx,qy
def rotate(origin,point,roll):
ox,oy = origin
px,py = point
angle=math.radians(roll)
#clockwise
qx= ox+ math.cos(angle)*(px-ox)+math.sin(angle)*(py-oy)
qy= oy+ math.sin(angle)*(px-ox)+math.cos(angle)*(py-oy)
return qx,qy
app=Tk()
app.title("Python GUI Application ")
name=ttk.Label(app, text="Draw basic line")
name.pack()
canvas=Canvas()
canvas.pack()
canvas.config(width=480,height=360)
filename = open('d:\detect\log_file\Attitude_data_Manual_1232018_1215.txt','r')
pitch,roll=[],[]
lineno = 0
lineno = read_file(lineno)
for m in range(0,lineno,1):
x0=-400
x1=880
y0=180
y1=180
xc=240
yc=180
point1= (x1,y1)
point= (x0,y0)
origin= (xc,yc)
x0,y0=rotate(origin,point,roll[m]*10)
y0=y0-(pitch[m]*60)
canvas.move(point,x0,y0)
x1,y1=counterrotate(origin,point1,roll[m]*10)
y1=y1-(pitch[m]*60)
canvas.move(point,x1,y1)
line1=canvas.create_line(x0,y0,x1,y1,fill='green',width=1)
blue_point= [x0,y0,x1,y1,480,0,0,0]
green_points=[x0,y0,x1,y1,480,360,0,360]
blue_poly=canvas.create_polygon(blue_point,fill='sky blue',width=2)
green_poly=canvas.create_polygon(green_points,fill='green',width=2)
canvas.create_line(0,180,480,180,fill='black',width=1)
canvas.update()
time.sleep(0.1)
canvas.delete(line1)
canvas.delete(green_poly)
canvas.delete(blue_poly)
app.mainloop()
答案 1 :(得分:0)
您必须避免在GUI中使用time.sleep()
,因为它会阻止事件循环,因此会生成它无法正确更新。我没有花时间审查出了什么问题,但提出了正确的实施方案。
我的解决方案建议有一个通过信号每隔一定时间间隔提供数据的类,以生成我使用QTimer
的时间间隔。
小部件获取数据并按您的意愿执行计算。
import sys
import math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
def counterrotate(origin,point1,roll):
ox,oy = origin
px,py = point1
angle=math.radians(roll)
#counterclockwise
qx= ox+ math.cos(angle)*(px-ox)-math.sin(angle)*(py-oy)
qy= oy+ math.sin(angle)*(px-ox)+math.cos(angle)*(py-oy)
return qx,qy
def rotate(origin,point,roll):
ox,oy = origin
px,py = point
angle=math.radians(roll)
#clockwise
qx= ox+ math.cos(angle)*(px-ox)+math.sin(angle)*(py-oy)
qy= oy+ math.sin(angle)*(px-ox)+math.cos(angle)*(py-oy)
return qx,qy
class Manager(QObject):
changedValue = pyqtSignal(tuple)
def __init__(self):
QObject.__init__(self)
filename = "Attitude_data_Manual_1232018_1158.txt"
res = self.read_content(filename)
self.results = zip(*res)
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_value)
self.timer.start(100)
@pyqtSlot()
def update_value(self):
try:
self.changedValue.emit(next(self.results))
except StopIteration:
self.timer.stop()
#QCoreApplication.instance().quit()
def read_content(self, filename):
pitch = []
roll = []
with open(filename,'r') as f :
lines = f.readlines()[4:]
for s in lines:
a = s.split()
if len(a) !=14:
print("point reached")
continue
pitch.append(float(a[4]))
roll.append(float(a[6]))
return pitch, roll
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.v = None
@pyqtSlot(tuple)
def update_value(self, v):
self.v = v
self.update()
def paintEvent(self, event):
QWidget.paintEvent(self, event)
painter = QPainter(self)
r = self.rect()
if self.v:
x0, x1, y0, y1, xc, yc = -400, 880, 180, 180, 240, 180
point1 = (x1,y1)
point = (x0,y0)
origin = (xc,yc)
pitch, roll = self.v
x0,y0 = rotate(origin, point, roll*10)
y0 -= pitch*60
x1, y1 = counterrotate(origin,point1, roll*10)
y1 -= pitch*60
posx0 = QPoint(x0, y0)
posx1 = QPoint(x1, y1)
upper_polygon = QPolygonF([r.topLeft(), posx0, posx1, r.topRight()])
bottom_polygon = QPolygonF([posx0, posx1, r.bottomRight(), r.bottomLeft()])
painter.setBrush(QColor("skyblue"))
painter.drawPolygon(upper_polygon)
painter.setBrush(QColor("green"))
painter.drawPolygon(bottom_polygon)
painter.drawLine(r.left(), r.center().y(), r.right(), r.center().y())
if __name__ == '__main__':
app = QApplication(sys.argv)
manager = Manager()
w = Widget()
manager.changedValue.connect(w.update_value)
w.show()
sys.exit(app.exec_())