その背景を簡単に説明しましょう。SoftimageXSIと呼ばれる3Dアプリケーション内でカスタムメニューシステムを開発しています。すでに作成されたPyQtアプリケーションオブジェクトがあり、ProcessEventsは毎秒特定の回数呼び出されるため、PyQtアプリケーションはXSI内で非モーダル状態で存在できます。
メニューを実装するために、PyQtメニューを表示するために作成したXSIのプラグインを呼び出すツールバーに埋め込まれたWebページがあります。これはすべて正常に機能します(ただし、少し工夫されています!)。
問題は、メニューを表示するときに、クリックしてもメニューが消えないことです。メニューの上にマウスを移動してからクリックすると、メニューが消えます。それが最初にポップアップするときだけです。
私は考えられるすべてを試しました。リストは次のとおりです。
- QtGui.qApp.installEventFilter(menu)を使用して、マウスが押された信号をキャッチしようとします。トリガーされることはありません。アプリケーション自体がクリックを受信していないのではないかと思います。
- menu.raise_()を使用しても違いはありません
- QtGui.qApp.setActiveWindow(menu)も同様です
- またはmenu.setFocus()
私も試しました:
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier) QtGui.qApp.sendEvent(menu, event)
自分でQEventLoopを作成しようとしましたが、XSIがクラッシュしました。もう一方の内部でモーダルループを実行しようとすることは、おそらく合法的なことではないと思います。それか、私が何をしているのか本当にわかりません(同じように可能性があります)
私が部分的に成功しているのは、grabMouse()を使用することだけです。これにより、メニューから離れてクリックするとメニューが閉じます(マウスがメニューを1回通過した後のみ)が、「スティック」するには数回呼び出す必要があります。
だからこれは今のところ私のコードです:
class MyMenu (QtGui.QMenu):
def __init__(self, parent = None):
QtGui.QMenu.__init__(self, parent)
self.grabbed=2
def getMouse(self):
if self.grabbed>0:
self.grabMouse()
self.grabbed-=1
def paintEvent(self, event):
QtGui.QMenu.paintEvent(self, event)
self.getMouse()
def hideEvent(self, event):
self.releaseMouse()
def ShowMenu():
menu = MyMenu()
menu.addAction("A")
menu.addAction("B")
menu.addAction("C")
submenu = MyMenu()
submenu.addAction("D")
submenu.addAction("E")
submenu.addAction("F")
menu.addMenu(submenu)
menu.setTearOffEnabled(True)
menu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setTitle("Window")
submenu.setTearOffEnabled(True)
pos = QtGui.QCursor.pos()
pos.setX(105)
menu.popup(pos)
#Prevent garbage collection
QtGui.XSIMenu=menu
QtGui.XSISubMenu=submenu
#Desperate acts!
menu.raise_()
QtGui.qApp.setActiveWindow(menu)
menu.setFocus()
これが私を狂わせているので、どんな考えやランダムな提案も非常にありがたいことに受け取られます!私はPyQtに比較的慣れておらず、何かを見逃している可能性があるので、私がすでに試したものへの変更を提案することを恐れないでください。
どうもありがとう、アンディ