Python 3.x 已解决:尝试使用GTK&;线程时出现错误;Pycairo(绘制窗口并从另一个线程发出信号) 解决方案 删除通道和相关代码 在窗口类中添加一个新的更新函数,该函数将新形状作为参数 修改类的初始化 调用update函数 解决方案的修改
抱歉,但是差异降价似乎没有正确显示,希望您仍然能够了解解决方案的工作原理 窗口类 在类方法中init_uiPython 3.x 已解决:尝试使用GTK&;线程时出现错误;Pycairo(绘制窗口并从另一个线程发出信号) 解决方案 删除通道和相关代码 在窗口类中添加一个新的更新函数,该函数将新形状作为参数 修改类的初始化 调用update函数 解决方案的修改,python-3.x,multithreading,gtk3,pygtk,pycairo,Python 3.x,Multithreading,Gtk3,Pygtk,Pycairo,抱歉,但是差异降价似乎没有正确显示,希望您仍然能够了解解决方案的工作原理 窗口类 在类方法中init_ui self.connect("delete-event", Gtk.main_quit) + self.show_all() + a = self.darea.get_allocation() + print (a.x, a.y, a.width, a.height) + self.img = cairo.ImageS
self.connect("delete-event", Gtk.main_quit)
+ self.show_all()
+ a = self.darea.get_allocation()
+ print (a.x, a.y, a.width, a.height)
+ self.img = cairo.ImageSurface(cairo.Format.RGB24, a.width, a.height)
一种新的类方法更新形状
+ def update_shapes(self, shapes):
+ self.shapes = shapes
+ cr = cairo.Context(self.img)
+ self.draw_background(cr)
+ for shape in self.shapes:
+ shape.draw(cr)
+ self.darea.queue_draw()
+ return True
主代码
问题:
窗口类
导入cairo
导入gi
输入数学
gi.require_版本('Gtk','3.0')
从gi.repository导入Gtk,GObject
类行():
定义初始(自身、开始、结束、厚度、颜色):
self.start=开始
self.end=结束
自身厚度=厚度
颜色
def抽取(自,cr):
cr.move_to(*自启动)
cr.line_至(*自结束)
cr.set_源_rgba(*自身颜色)
cr.set\U线条宽度(自身厚度)
cr.中风()
类多边形():
定义初始值(自身、点、线颜色、线厚度、填充颜色=无):
self.points=点#点应该是点的iterable
self.line\u color=line\u color
self.line\u厚度=line\u厚度
自填充颜色=填充颜色
def抽取(自,cr):
cr.move_to(*自身点[0])
对于自身中的点。点[1:]:
cr.line_至(*点)
cr.关闭_路径()
cr.set\U源\U rgba(*自身线条\U颜色)
cr.set线宽度(自线厚度)
cr.中风()
如果自填充颜色不是无:
cr.move_to(*自身点[0])
对于自身中的点。点[1:]:
cr.line_至(*点)
cr.关闭_路径()
cr.set\U源\U rgba(*自填充\U颜色)
cr.fill()
类窗口(Gtk.Window):
__G信号\uuuu={
“更新信号”:(GObject.signal\u RUN\u优先,无,
())
}
def do_更新_信号(自身):
打印(“调用更新信号”)
self.shapes=self.shapes\u channel.read()
打印(“新形状数:”,len(self.shapes))
self.show_all()
def uuu init uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
超级(窗口,自我)。\uuuu初始化
self.width=窗口大小[0]
self.height=窗口大小[1]
self.background\u color=背景颜色
self.title=标题
self.shapes=[]
self.shapes\u channel=shapes\u channel
self.init_ui()
def初始用户界面(自身):
darea=Gtk.DrawingArea()
darea.connect(“绘制”,自绘制)
self.add(darea)
self.set_title(self.title)
self.resize(self.width、self.height)
自我设置位置(Gtk.WindowPosition.CENTER)
self.connect(“删除事件”,Gtk.main_退出)
def draw_背景(self,cr:cairo.Context):
cr刻度(自宽、自高)
cr.矩形(0,0,1,1)#矩形(x0,y0,x1,y1)
cr.set\U源\U rgba(*自身背景颜色)
cr.fill()
图纸上的定义(self、wid、cr:cairo.Context):
自绘制背景(cr)
对于self.shapes中的形状:
形状绘制(cr)
def运行(自):
Gtk.main()
def新建_窗口(形状_通道,
窗口大小=(10001000),
背景颜色=(1,1,1,1),
title=“3yp”):
返回窗口(U形通道,
窗口大小=窗口大小,
背景颜色=背景颜色,
头衔=头衔)
我正在尝试运行一个可以绘制我定义的形状(直线和多边形)的窗口
以前,当我向它提供一个形状列表并在应用程序结束时运行它时,它工作得很好
但是,我正在尝试添加交互性,并在调用update_信号时让它重新绘制一个形状列表,并在作为构造函数一部分的shapes_通道中传递一个新形状列表
主代码
以下是我的主代码中的相关位:
shapes\u channel=channel()
iter_num=0
def优化(chan、prob、信号员):
def打印编号(xk):
全球国际热核聚变实验堆
iter_num+=1
问题更新位置(xk)
概率更新梯度(雅可比(xk))
新形状=转换网格(prob.grid,building\u size=1.0/网格大小)
chan.write(新形状)
信号员发出(“更新信号”)
打印(“迭代”,iter_num,“完成…”)
尝试:
sol=minimize(objective,x0,bounds=all_bounds,constraints=constraints,options={'maxiter':MAX_ITER,'disp':True},callback=print_ITER_num,jac=jacobian)
问题更新位置(sol.x)
例外情况除外,如e:
打印(“遇到错误”,e)
窗口=新窗口(形状通道=形状通道)
线程(target=optimize,args=(shapes\u channel,optim\u problem,window))
x、 开始()
window.run()
如你所见:
调用更新信号
新形状数:31
Gdk消息:01:27:14.090:main.py:X服务器上的致命IO错误0(成功):0。
从控制台输出中,我们可以推断信号被成功调用,新形状被传递到窗口并正确存储,但在行self.show_all()
中失败
这是一个以前运行良好的对象,并生成图形输出,我只能想到2个位置
+ def update_shapes(self, shapes):
+ self.shapes = shapes
+ cr = cairo.Context(self.img)
+ self.draw_background(cr)
+ for shape in self.shapes:
+ shape.draw(cr)
+ self.darea.queue_draw()
+ return True
- shapes_channel = Channel()
iter_num = 0
- def optimize(chan, prob, signaller):
+ def optimize(prob, signaller):
def print_iter_num(xk):
global iter_num
iter_num += 1
prob.update_positions(xk)
prob.update_grads(jacobian(xk))
new_shapes = convert_grid(prob.grid, building_size=1.0/GRID_SIZE)
- chan.write(new_shapes)
- signaller.emit("update_signal")
+ GLib.idle_add(signaller.update_shapes, new_shapes)
print("Iteration", iter_num, "complete...")
try:
sol = minimize(objective, x0, bounds = all_bounds, constraints=constraints, options={'maxiter': MAX_ITER, 'disp': True}, callback=print_iter_num, jac=jacobian)
prob.update_positions(sol.x)
except Exception as e:
print("ran into an error", e)
- window = new_window(shapes_channel=shapes_channel)
+ window = new_window()
- x = threading.Thread(target=optimize, args=(shapes_channel, optim_problem, window))
+ x = threading.Thread(target=optimize, args=(optim_problem, window))
x.start()
window.run()