2012-08-24 37 views
0

我已經看到很多關於在子進程或線程中運行代碼的東西,並且使用了multiprocessingthreading模塊,這非常簡單。但是,在GUI中這樣做會增加額外的複雜性。在一個子進程中執行python腳本 - 使用圖形

從我所瞭解的情況來看,如果您嘗試從多個線程(或進程)操縱它們,GUI類不會喜歡它。解決方法是將數據從您創建它的任何線程發送到負責圖形的線程,然後將其呈現在那裏。

不幸的是,對於我想到的情況,這不是一個選項:我創建的GUI允許用戶編寫自己的繪圖代碼,然後執行。這意味着我無法控制他們如何精確繪製,也不想擁有它。 (更新:這些圖被顯示在單獨的窗口中,並且不需要被嵌入主GUI中的任何位置。我想要的是讓它們與主GUI分離存在,而不共享任何底層的圖形庫。)

那麼,我現在不知道是

是否有與自己聯繫的窗口系統一個全新的解釋實例上執行的Python代碼串的一些乾淨的(ISH)的方式?


響應於該評論:

當前應用程序被設置爲如下:一個簡單的Python腳本加載的wxPython GUI(一個wx.App)。使用這個gui用戶可以設置一個模擬,其中一部分涉及用普通python創建一個腳本,該腳本運行模擬並對結果進行後處理(通常涉及製作圖並顯示它們)。目前我只需在腳本代碼上調用exec()即可完成此操作。這工作正常,但gui在仿真運行時凍結。我已經嘗試在子進程中運行嵌入式腳本,這也可以正常工作,直到您嘗試顯示創建的圖(通常使用matplotlib的show())。在這一點上,一些深藏在wxPython,wx,gtk等堆棧中的庫開始抱怨,因爲你無法從多個線程操縱它。 我想的設置的設置大致相同,但不是與主應用程序共享GUI的嵌入式腳本,而是希望它在自己的環境中顯示圖形。

而只是爲了澄清:

這是不是有關問題:「我該怎麼辦多線程/多」,甚至是「我如何做一個單一的wxPython GUI中的多線程/多」。問題是我怎樣才能從開始一個腳本gui加載完整的新的 gui。我如何讓窗口管理器將此腳本看作完全獨立的應用程序?

最簡單的方法是將其生成在某個臨時文件夾中,然後對python解釋器進行非阻塞調用,但這會使通信更加困難,並且很難知道何時可以刪除臨時文件。我希望有一個更乾淨,更動態的方式來做到這一點。

+1

我不確定您的應用程序和進程是如何設置的。你能描述一下你今天擁有什麼,以及你想如何擁有它? – Macke

+0

什麼(如果有)數據在您的應用程序和腳本之間共享? – Macke

+0

幾乎沒有。一個未被主GUI使用的對象被傳遞給嵌入式腳本。如果可能,應該捕獲腳本輸出的文本並將其傳回主GUI。 –

回答

1

你可以簡單地使用subprocess來運行'python.exe'並在腳本中輸入腳本嗎?

或者,multiprocessing軟件包應該足夠了,如果您想要將一些(可醃製的)數據移動到您運行腳本的新進程中。只需創建一個運行該腳本的函數/可調用對象,並創建一個可調用對象作爲目標。這樣,您應該能夠傳遞一些數據,而不會出現GUI問題。

用任何一個捕獲文本都很容易,子流程允許這一點,而不是更多。使用多進程,您可以更輕鬆地來回傳遞Python對象。

+0

傳遞數據不是問題,從兩個線程繪圖是:) 這就是爲什麼你的第一個建議:在一個子進程中運行python.exe可能是最好的主意:D雖然沒有真的那麼... –

1

在Windows上,您可以使用另一個進程的父窗口創建窗口,然後對其進行繪製。 請參閱CreateWindowEx的hWndParent參數。

如果wxWindows支持顯式獲取/設置,那麼你應該很好。 根據您的平臺,在任何Windows系統中都可能有類似的情況。

因此,只要讓用戶能夠找到應用程序窗口的句柄,就可以讓他們選擇在自己的進程中運行時隱藏在應用程序中的視圖上。

+0

謝謝!但我真的需要一個便攜式解決方案,如果僅僅因爲我自己是一個linux用戶:) –

1

我對wx沒有多少了解,我使用jython(用java實現的python,可以使用java)和swing。 Swing有它自己的工作線程,如果你做了gui更新,你可以將你的代碼包裝到一個可運行的程序中,並用swing.invokelater來調用它。

你可以看到wx是否有類似的東西,如果你只允許從你創建的線程中操作gui,可以嘗試類似的東西。爲你的gui創建一個代理對象,它將所有的調用轉發給你的線程,並將它們轉發給gui。

但代理這樣會變得混亂。那麼你如何讓他們用一個'updateGui'函數來定義類,他們應該通過一個隊列交給你,並且你將在你的GUI線程中執行。

1

在wxPython中使用線程時,必須使用線程安全的方法與GUI進行通信:wx.CallAfter,wx.CallLater或wx.PostEvent。在你的情況下,我會在一個單獨的線程/進程中運行任何長時間運行的代碼,當它完成它的處理時,將結果發送到GUI。 GUI可以實例化一個新框架,並使用matplotlib或PyPlot來顯示劇情,具體取決於您想要走哪條路。我聽說你也可以使用FloatCanvas來繪製陰謀。無論如何,如果你正確地實例化新框架,那麼你可以實例化N個框架並顯示它們,並且沒問題。請參閱wxPython wiki以獲取使用wx的線程示例:http://wiki.wxpython.org/LongRunningTasks

+0

感謝您的回覆!這裏的問題是我沒有任何控制用戶使用的繪圖方法(matplotlib,或完全不同的東西),我不想規定任何東西。管道數據返回,共享排隊等是我熟悉的東西,但在這種情況下,我想完全繞過它,並將腳本作爲完全獨立的應用程序運行。 –

+0

那麼如果繪圖可以以任何方式完成,並且您希望它們分開運行,那麼您應該只使用Python的子流程模塊。當然,這些模塊必須是獨立的wxPython腳本。或者他們可能是PyQT或者其他任何東西。 –

+0

謝謝!我已經嘗試過使用多處理模塊,但是干擾正在運行的應用程序,會嘗試使用子進程模塊是否有任何不同... –

相關問題