2016-01-21 104 views
0

我有一個PyQt GUI,我使用上下文菜單動作來執行一個功能。這個函數啓動一個matplotlib交互,我使用鼠標在圖像頂部繪製。我可以強制matplotlib在PyQt線程/進程中阻塞嗎?

問題是,當我通過PyQt上下文菜單操作調用該函數時,plt.show(block = True)不會阻止該線程上的執行,並且我無法與matplotlib窗口進行交互。

或多或少在代碼中發生的情況如下所示。當我在項目上右擊PyQt的小工具,我得到的上下文菜單:

@QtCore.pyqtSlot(QtCore.QModelIndex, QtCore.QPoint) 
def on_contextMenuClicked(widget, qtindex, pos): 
    menu = QtGui.QMenu(widget) 
    shortcut = QtGui.QKeySequence(0) 
    action = menu.addAction('edit mask', edit_mask_func, shortcut) 
    menu.exec_(widget.mapToGlobal(pos)) 

然後當我點擊編輯屏蔽功能調用這個函數:

import matplotlib.pyplot as plt 
import numpy as np 

def edit_mask_func(): 
    # code to start a matplotlib interaction 
    plt.ion() 
    fig = plt.figure(1) 
    ax = plt.subplot(111) 
    imgOver = np.zeros(img.shape, np.uint8) + 255 
    ax.imshow(img, interpolation='nearest', alpha=1) 
    ax.imshow(imgOver, interpolation='nearest', alpha=0.6) 
    ax.grid(False) 

    # This code handles the matplotlib interactive stuff 
    # like setting up callbacks 
    # eg: fig.canvas.mpl_connect('motion_notify_event', on_move) 
    # and doing blit stuff. 
    pntr = Painter(fig, ax, imgOver) 
    plt.title('Click on the image to draw. exit to finish') 

    # THIS SHOULD BLOCK, BUT IT DOES NOT IF A CALLED BY 
    # QT INSTEAD OF THE MAIN THREAD 
    plt.show(block=True) 

    return pntr.img 

如果我打電話edit_mask_func從主線程工作得很好。看來,如果我通過一個PyQt線程調用函數,這只是一個問題。

東西告訴的是,如果我嘗試強制程序通過投入的raw_input /輸入呼叫阻止那裏,我得到這個在標準輸出:

>>> input('hack to block... press enter when done') 
QCoreApplication::exec: The event loop is already running 
hack to block... press enter when doneQCoreApplication::exec: The event loop is already running 

最後,我需要用整合這種互動一個回調系統,但我希望我現在可以做一些快速和骯髒的事情。沒有任何方法可以輕鬆完成而無需編寫回調函數?

我目前正在matplotlib_version 1.5.0和PyQt4_version運行4.10.4

+0

有很多關於你的代碼的事情還不清楚,但它看起來像你正在從一個GUI相關的調用輔助線程。 PyQt(matplotlib使用的)不是線程安全的,如果繼續這個路徑,你會得到段錯誤。如果您需要線程化,請確保所有與GUI相關的代碼都在主線程中執行,方法是從連接到主線程插槽的輔助線程發出信號。 –

回答