Gtk非阻塞呼叫解决方案?

问题描述:

Hello guys Iam在python中编写Gtk + GUI应用程序,它使用onvif Iam在应用程序内使用异步调用来播放视频和移动摄像头。但是,当按下其中一个按钮移动摄像头视频时,当按钮被按下时没关系,但是当它被释放时它会再次挂起。Gtk非阻塞呼叫解决方案?

ONVIF连续移动类

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播放器类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() 

如果您能指出我在这里做错了什么,以及为什么视频挂起,我将不胜感激。

PS:

没有粘贴整个代码,因为它是巨大的,我希望你会明白这个问题。

编辑:

我说我的球员对象和RenderArea对象的初始化,因为我认为这是相关的这个问题。 我初始化Player对象并发送它RenderArea,以便它可以渲染视频。 现在的问题是可以在某种方式按钮控件块RenderArea小部件?

我将详细解释发生了什么。例如,当我按下DOWN按钮时,它冻结了第二秒的视频,它看起来像跳过几帧。几乎所有东西都没有,似乎没有任何工作。问题不在RenderArea和Gstreamer问题是移动方法和/或按钮按下事件。

+0

'self.Camera'如何设置?当'ContinuousMove()'线程启动时? – jfs 2014-10-30 09:36:52

+0

要避免进一步的狩猎,请创建[一个演示您的问题的最小完整代码示例](http://stackoverflow.com/help/mcve):使代码按原样运行,删除所有不相关的代码(如果问题仍然存在如果你删除了代码,那么它是不相关的),用存根替换阻塞调用(例如'time.sleep(10)',而不是发出网络请求或使用'time.sleep(1)'并打印'time.time )'价值,而不是播放视频)等 – jfs 2014-10-30 09:41:26

+0

对于第一个问题检查编辑上面。我会试试看,这个问题困扰了我几天它不是那么大,但我想在每一个时刻流畅的视频播放。我发现应用程序叫做Winpdb进行调试,但问题在于它是针对python 2.7的。我想知道是否有任何良好的python3调试工具,所以我可以追踪按下按钮时发生的情况。 – user3820641 2014-10-30 09:57:34

on_down_pressed()看起来像一个事件处理程序。如果它阻塞,则GUI“冻结”(不响应)。

with -statement调用executor.shutdown(wait=True)退出时阻止该方法。 为了避免在Camera.move()方法中阻塞,请将创建的ThreadPoolExecutor()移动到__init__(),并且只拨打executor.submit(),但不会在那里阻止。

+0

尝试过,但仍然挂起,当我尝试移动camera.See编辑更多信息 – user3820641 2014-10-30 08:26:22

+0

@ user3820641:'move(self,x,y,zoom)'方法仍然阻塞在您的代码中。 – jfs 2014-10-30 09:10:27

+0

抱歉,由于某种原因,它没有保存编辑。 – user3820641 2014-10-30 09:33:24