[英]Gtk non blocking calls solution?
大家好Iam用python编写Gtk + GUI应用程序来播放视频并使用onvif移动摄像机Iam在应用程序中使用异步调用SOAP服务调用Iam。但是发生的是,当我按下移动摄像机视频的按钮之一挂了一秒钟然后就可以了按下按钮时,但释放时再次挂起。
class ContinuousMove(threading.Thread):
def __init__(self,onvif_service):
threading.Thread.__init__(self)
self.start()
self.onvif_service=onvif_service
self.position=self.onvif_service.get_client().factory.create('ns4:PTZVector')
self.profileToken=self.onvif_service.get_client().factory.create('ns4:ReferenceToken')
self.speed=self.onvif_service.get_client().factory.create('ns4:PTZSpeed')
self.timeout=self.onvif_service.get_client().factory.create('ns4:Timeout')
self.executor=concurrent.futures.ThreadPoolExecutor(max_workers=1)
def move(self,x,y,zoom):
future = self.executor.submit(self.__move__,x,y,zoom)
def __move__(self,x,y,zoom):
self.position.PanTilt._x=x
self.position.PanTilt._y=y
self.position.Zoom._x=zoom
self.profileToken='media_profile1'
self.onvif_service.get_client().service.ContinuousMove(self.profileToken,self.position)
如您所见,我使用conncurent.future模块及其类ThreadPoolExecutor进行异步调用
接下来,我在扩展Gtk.Window的播放器类中创建ContinuousMove类的实例,然后创建按钮并设置事件回调。
class player(Gtk.Window):
#bunch of functions
def __init__(self):
Gtk.Window.__init__(self):
self.gui_init()
self.camera=ContinuousMove(onvif_service)
self.player=Player(self.previewArea)#class which constructs gstreamer pipeline and renders it on previewArea
def gui_init(self):
self.previewArea=Gtk.RenderArea()
self.buttonDown=Gtk.Button("DOWN")
self.buttonDown.connect("pressed",self.on_down_pressed)
def on_down_pressed(self,btn):
#instance of ContinuousMove
self.Camera.move(0,-0.1,0)
app=player()
app.show_all()
Gtk.main()
如果您能指出我在这里做错了什么以及视频为什么挂起,将不胜感激。
没有粘贴整个代码,因为它是巨大的,希望您能从中理解问题。
我添加了Player对象和RenderArea对象的init,因为我认为它与该问题有关。 我初始化Player对象并将其发送给RenderArea,以便它可以向其渲染视频。 现在的问题是按钮小部件可以某种方式阻止RenderArea小部件吗?
我将详细解释发生的情况,例如,当我按下DOWN按钮时,它冻结了第二秒钟的视频,看起来好像跳过了几帧。尝试了几乎所有内容,但似乎没有任何作用。问题不是RenderArea或Gstreamer问题是move方法和/或按钮按下事件。
on_down_pressed()
看起来像一个事件处理程序。 如果阻塞,则GUI“冻结”(不响应)。
with
-statement会在退出该方法的退出时调用executor.shutdown(wait=True)
。 为了避免在Camera.move()
方法中发生阻塞,请将ThreadPoolExecutor()
的创建移动到__init__()
并仅调用在此不阻塞的executor.submit()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.