Gtk无阻塞调用解决方案



大家好,我正在python中编写Gtk+GUI应用程序,该应用程序使用onvif Iam播放视频并移动相机,使用应用程序中SOAP服务的异步调用。但实际情况是,当我按下其中一个移动相机的按钮时,视频会挂起一秒钟,然后在按下按钮时它是可以的,但当它释放时,它会再次挂起。

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进行异步调用

接下来,我在播放器类中创建ContinuousMove类的实例,该类扩展了Gtk.Window然后我创建按钮并设置事件回调。

    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:

没有粘贴整个代码,因为它太庞大了。我希望你能从中理解问题。

编辑:

我添加了Player对象和RenderArea对象的init,因为我认为它与这个问题有关。我初始化Player对象并发送它RenderArea,这样它就可以向它渲染视频。现在的问题是按钮小部件会以某种方式阻止RenderArea小部件吗?

我会详细解释会发生什么。例如,当我按下DOWN按钮时,它会冻结视频一秒钟,看起来就像跳过了几帧。尝试了几乎所有的东西,但似乎都不起作用。问题既不是RenderArea,也不是Gstreamer问题是移动方法和/或按钮按下事件。

on_down_pressed()看起来像一个事件处理程序。如果它被阻止,那么GUI就会"冻结"(不响应)。

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

相关内容

最新更新