2014-10-29 156 views
0

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

回答

0

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