QToolButton всплывающее меню только при нажатии и удержании
Я пытаюсь реализовать кнопку "Открыть" так, чтобы, если пользователь нажимает ее и удерживает, появится меню приложений, из которых пользователь может выбрать; но как только пользователь отпускает мышь, меню должно исчезнуть. если пользователь отпускает мышь, не выбирая приложение в меню, он должен открыть файл с приложением по умолчанию. Я реализую эту кнопку как QToolButton
и подключите сигналы следующим образом:
self.ui_open_btn.pressed.connect(self._onOpenBtnPressed)
self.ui_open_btn.triggered.connect(self._onOpenBtnTriggered)
def _onOpenBtnPressed(self):
self.ui_open_btn.showMenu()
def _onOpenBtnTriggered(self, action):
application_name = action.text()
# code to launch the application
Прямо сейчас, когда пользователь нажимает кнопку, появится меню. Тем не менее, меню все еще там, когда пользователь отпускает кнопку, и действие в меню запускается нажатием на нее. Я пробовал под обоими DelayedPopup
а также InstantPopup
Режим. Пока меню было установлено для self.ui_open_btn
Я больше не могу поймать released
сигнал. Как я могу скрыть меню, когда пользователь отпускает мышь? Как действие в меню может быть вызвано отпусканием мыши?
--added ---
Я нашел еще одну проблему с использованием QToolButton
: меню всегда появляется при нажатии кнопки. Вместо этого я хотел бы поймать pressed
сигнал, сделайте некоторую проверку, чтобы определить, должно ли всплывающее меню или нет. Поэтому я изменил свой подход к написанию своей настраиваемой кнопки инструментов путем создания подклассов QPushButton
а также QMenu
, Пожалуйста, смотрите мой код в ответе ниже.
Благодарю.
2 ответа
Мне удалось достичь того, что я хочу, путем подклассов QPushButton
а также QMennu
:
class MyMenu(QtGui.QMenu):
""" Custom menu which will close when mouse is released. ""'"
def mouseReleaseEvent(self, event):
action = self.actionAt(event.pos())
self.triggered.emit(action)
self.close()
class MyButton(QtGui.QPushButton):
triggered = QtCore.pyqtSignal("QAction")
def __init__(self, menu=None, parent=None):
super(MyButton, self).__init__(parent)
self.setMenu(menu)
def menu(self):
return self._menu
def setMenu(self, menu):
self._menu = menu if menu else MyMenu(self)
self._menu.triggered.connect(self.triggered.emit)
и в QDialog
содержащий эту кнопку, я делаю следующее:
menu = MyMenu(self)
# insert here code to add actions to menu
self.open_btn = MyButton(parent=self, menu=menu)
self.open_btn.pressed.connect(self._onOpenBtnPressed)
self.open_btn.triggered.connect(self._onOpenBtnTriggered)
def _onOpenBtnPressed(self):
# insert here code to check whether we should pop up the menu
pos = self.mapToGlobal(self.open_btn.pos())
pos.setY(pos.y() + self.open_btn.height())
self.open_btn.menu().move(pos)
self.open_btn.menu().show()
def _onOpenBtnTriggered(self, action):
if action:
application_name = str(action.text())
# insert here code to launch this application
else:
# insert here code to launch the default application
self.close() # close this dialog
Создайте пользовательский QToolButton, который будет фильтровать события из меню и реагировать на событие отпускания мыши, полученное меню:
class MyToolButton(QtGui.QToolButton):
def __init__(self, *args):
QtGui.QToolButton.__init__(self, *args)
def eventFilter(self, menu, event):
if event.type() == QtCore.QEvent.MouseButtonRelease:
if self.underMouse():
menu.close()
# and now do default action
print "doing default action"
return True
return False
Установите фильтр событий после того, как вы установили меню:
self.ui_open_btn.menu().installEventFilter(self.ui_open_btn)