LINUX.ORG.RU

внешнее управление pyqtgraph-окном

 , ,


0

1

Например, у меня есть класс, реализующий pyqtgraph-окно в котором рисуются некоторые графики. В классе есть функция update для изменения отрисовки или содержания. В прилагающихся примерах много вариантов, когда вызов update привязывается к событиям посылаемым окном, а как сделать этот вызов из внешнего кода? Имеется ввиду, что код создаёт окно, но дальше оно живёт само по себе, а код сам по себе, но периодически он посылает окну апдейты.

Правильно я понимаю, что это окно нужно создавать в отдельном треде, а уже там запускать app.exec_()? Как лучше организовать взаимодействие?

★★★★★

Последнее исправление: thunar (всего исправлений: 1)

Надо больше информации, например, нужно ли вешать логику между кодом и окном при дерганье. Окно всегда лучше в отдельном треде, чтобы оно не зависело от загруженности основного вычислительного потока. Хотя в виндовс пляшут от окна часто, т.е. окно основной процесс, а вычисления в других.

Хотя ты про питон, если там тебе потоки нужны, то подумай над тем, что тебе надо не на питоне это делать. Так что пляши от процессов, GIL то никто пока не отменял. Есть конечно воркэроунд, вот такой. Но это только в планах было на момент публикации, может в четвёртом переделают, пока не верю что смогут от GIL избавиться.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 7)

По таймеру. Например раз в 100 миллисекунд перерисовываешь окошко, для статичных графиков нормально.

Zpp
()

Пока как-то так получилось:

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg

class osc_ui(object):

	def __init__(self, rows):
		self.win = pg.GraphicsLayoutWidget(show=True)
		self.axs = [self.win.addPlot(col=0,row=i) for i in range(rows)]
		self.plt = [ax.plot() for ax in self.axs]
		for ax in self.axs[1:]:
			ax.setXLink(self.axs[0])
		
	def update(self, x, *ys):
		for plot,y in zip(self.plt, ys):
			plot.setData(x, y)
		pg.QtGui.QApplication.processEvents()

def gen_data():
	xs = np.linspace(-10,10,10001)
	ys = np.random.normal(0,1,size=xs.shape)
	zs = np.random.normal(0,1,size=xs.shape)
	time.sleep(1/10)
	return xs,ys,zs

if __name__ == '__main__':

	ui = osc_ui(2)
	while True:
		print("gen data, ",end="")
		data = gen_data()
		
		print("redraw")
		ui.update(*data)
Но это в текущем треде, так, конечно, теряется интерактивность.

thunar ★★★★★
() автор топика
Последнее исправление: thunar (всего исправлений: 3)
Ответ на: комментарий от peregrine

например, нужно ли вешать логику между кодом и окном при дерганье

По хорошему, нужна двухсторонняя свзяь — код по мере поступления данных отправляет окну новые кривые, а из окна нужна возможность приостановить/продолжить цикл сбора данных, например, что бы получше рассмотреть интересующий кусок.

thunar ★★★★★
() автор топика
Ответ на: комментарий от thunar

Я честно потоками на питоне не занимался, в моих задачах одного достаточно, с потоками я привык работать в C#/C++, хотя давно не трогал, уже подглядывать надо, как оно правильно реализуется, но может это тебе поможет.

peregrine ★★★★★
()
Ответ на: комментарий от thunar

Ага, а наизнанку-то и нельзя

QApplication::exec: Must be called from the main thread
Клиент-сервер что ли делать...

thunar ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.