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问题是移动方法和/或按钮按下事件。
on_down_pressed()
看起来像一个事件处理程序。如果它阻塞,则GUI“冻结”(不响应)。
with
-statement调用executor.shutdown(wait=True)
退出时阻止该方法。 为了避免在Camera.move()
方法中阻塞,请将创建的ThreadPoolExecutor()
移动到__init__()
,并且只拨打executor.submit()
,但不会在那里阻止。
尝试过,但仍然挂起,当我尝试移动camera.See编辑更多信息 – user3820641 2014-10-30 08:26:22
@ user3820641:'move(self,x,y,zoom)'方法仍然阻塞在您的代码中。 – jfs 2014-10-30 09:10:27
抱歉,由于某种原因,它没有保存编辑。 – user3820641 2014-10-30 09:33:24
'self.Camera'如何设置?当'ContinuousMove()'线程启动时? – jfs 2014-10-30 09:36:52
要避免进一步的狩猎,请创建[一个演示您的问题的最小完整代码示例](http://stackoverflow.com/help/mcve):使代码按原样运行,删除所有不相关的代码(如果问题仍然存在如果你删除了代码,那么它是不相关的),用存根替换阻塞调用(例如'time.sleep(10)',而不是发出网络请求或使用'time.sleep(1)'并打印'time.time )'价值,而不是播放视频)等 – jfs 2014-10-30 09:41:26
对于第一个问题检查编辑上面。我会试试看,这个问题困扰了我几天它不是那么大,但我想在每一个时刻流畅的视频播放。我发现应用程序叫做Winpdb进行调试,但问题在于它是针对python 2.7的。我想知道是否有任何良好的python3调试工具,所以我可以追踪按下按钮时发生的情况。 – user3820641 2014-10-30 09:57:34