1

我们有一个 PyQt4/PySide Qt4 视频播放器应用程序,它在 GUI 中具有 QToolButton 对象以及关联的 QMenu,并添加了 QToolButton#setMenu()。目前,当用户与菜单交互时,它会接管事件循环并停止视频播放。事件循环接管发生在私有 QToolButtonPrivate::popupTimerDone() 中。

我们想重写/修改 QToolButton 使其不是无模式的,但似乎没有任何简单的选择:

  1. 在 C++ 中复制和修改 QToolButton,然后使用 PyQt4 或 PySide 的 C++ 包装为 Python 包装类。更简单,但现在我们的构建系统需要编译一个 C++ 类并知道它在哪个环境中运行,PySide 或 PyQt4。
  2. 在 Python 中完全重写 QToolButton,因此它会继承 QAbstractButton,并进行修改。大量需要重写和维护的代码。
  3. 在 Python 中,继承 QToolButton 并在必要时覆盖。这看起来不错,但是看看 QToolButtonPrivate::popupTimerDone() 引用的内部状态,无论如何我们大部分都会重写整个事情。

还有其他想法吗?

4

1 回答 1

1

我建议考虑使用 QToolButton.clicked 信号与 QMenu.popup 方法与 setMenu - 这可能会破坏模态。

我尝试为您设置一个示例 - 但它不会阻止 QMovie ......所以也许您可以使用此示例来测试视频播放器与 Qmovie 的不同选项,看看它是否仍然阻止您的事件循环:

from PyQt4 import QtGui, QtCore

MOVIE_FILE = '/path/to/ajax_loader.gif'

class MyDialog(QtGui.QDialog):
    def __init__( self, parent = None ):
        super(MyDialog, self).__init__(parent)

        self._menu = QtGui.QMenu(self)
        self._menu.addAction('Action A')
        self._menu.addAction('Action B')

        self._menuButton     = QtGui.QToolButton(self)
        self._modalButton    = QtGui.QToolButton(self)
        self._nonModalButton = QtGui.QToolButton(self)
        self._feedbackLabel  = QtGui.QLabel(self)
        self._startTime      = QtCore.QDateTime.currentDateTime()

        self._menuButton.setPopupMode(self._menuButton.InstantPopup)

        movie = QtGui.QMovie(self)
        movie.setFileName(MOVIE_FILE)
        movie.start()

        self._feedbackLabel.setMovie(movie)

        hlayout = QtGui.QHBoxLayout()
        hlayout.addWidget(self._menuButton)
        hlayout.addWidget(self._modalButton)
        hlayout.addWidget(self._nonModalButton)
        hlayout.addStretch()

        vlayout = QtGui.QVBoxLayout()
        vlayout.addLayout(hlayout)
        vlayout.addWidget(self._feedbackLabel)

        self.setLayout(vlayout)
        self.adjustSize()

        # setup different menu examples
        self._menuButton.setMenu(self._menu)
        self._modalButton.clicked.connect(self.showModalMenu)
        self._nonModalButton.clicked.connect(self.showNonModalMenu)

        self._menu.triggered.connect(self.showAction)

    def showModalMenu( self ):
        point = self._modalButton.rect().bottomLeft()
        global_point = self._modalButton.mapToGlobal(point)
        self._menu.exec_(global_point)

    def showNonModalMenu( self ):
        point = self._nonModalButton.rect().bottomLeft()
        global_point = self._nonModalButton.mapToGlobal(point)
        self._menu.popup(global_point)

    def showAction( self, action ):
        print action.text()

if ( __name__ == '__main__' ):
    app = QtGui.QApplication([])
    dlg = MyDialog()
    dlg.show()
    app.exec_()
于 2012-08-20T19:26:03.100 回答