简体   繁体   中英

Gtk non blocking calls solution?

Hello guys Iam writing Gtk+ GUI application in python which plays video and moves camera using onvif Iam using async calls for SOAP service within application.But what happens is that when I press one of the button for moving camera video hangs for a second then it's ok while button is pressed but when it's released it hangs again .

Onvif continuous move class

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)

As you see here I used conncurent.future module and their class ThreadPoolExecutor for async call

Next I create instance of ContinuousMove class in player class which extends Gtk.Window and then I create buttons and set event callbacks.

    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()

I would be grateful if you could point me what am I doing wrong here and why video hangs.

PS:

Didn't pasted whole code because it's gigantic I hope you'll understand the problem from this.

EDIT:

I added init of my Player object and RenderArea object because I think it's relevant for this problem. I init Player object and send it RenderArea so it can render video to it. Now question is could button widget block RenderArea widget in some way ?

I'll explain details what happens.For example when I press DOWN button it freezes video for the second it looks like it skips a few frames.Tried almost everything and nothing seems to work.The problem is not RenderArea nor Gstreamer problem is move method and/or button pressed event.

on_down_pressed() looks like an event handler. If it blocks then the GUI "freezes" (doesn't respond).

with -statement calls executor.shutdown(wait=True) on exit that blocks the method. To avoid blocking in Camera.move() method, move the creation of ThreadPoolExecutor() to __init__() and call only executor.submit() that doesn't block there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM