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