QToolButton нажал сигнал вызывается только один раз - PullRequest
0 голосов
/ 22 декабря 2018

Я прикрепил QMenu к кнопке QToolButton, в которой меню не отображается правильно.

Я заполняю свое QMenu от чтения файла .txt.В меню отображаются правильные элементы при первом запуске, но если я внес изменения в файл .txt и повторно нажал кнопку, QMenu по-прежнему отображает элемент при первом запуске.

Добавлениекажется, что сигнал clicked вызывается только один раз?

class MyWin(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyWin, self).__init__()
        central_widget = QtGui.QWidget()
        self.setCentralWidget(central_widget)
        vlay = QtGui.QVBoxLayout(central_widget)
        hlay = QtGui.QHBoxLayout()
        vlay.addLayout(hlay)
        vlay.addStretch()

        self.add_button = QtGui.QToolButton()
        self.tab_bar = QtGui.QTabBar(self)
        self.add_button.setIcon(QtGui.QIcon('add.png'))
        self.add_button.clicked.connect(self.set_menu)

        #self.add_button.setMenu(self.set_menu())
        #self.add_button.setPopupMode(QtGui.QToolButton.InstantPopup)

        self.tab_bar.setTabButton(
            0,
            QtGui.QTabBar.ButtonPosition.RightSide,
            self.add_button
        )
        hlay.addWidget(self.add_button)
        hlay.addWidget(self.tab_bar)

    def set_menu(self):
        with open('/Desktop/item_file.txt') as f:
            menu_options = f.read().splitlines()
            print menu_options

        qmenu = QtGui.QMenu(self.add_button)
        for opt in menu_options:
            qmenu.addAction(opt, partial(self.set_new_tab, opt))

        self.add_button.setMenu(qmenu)
        self.add_button.setPopupMode(QtGui.QToolButton.InstantPopup)

    def set_new_tab(self, opt):
        self.tab_bar.addTab(opt)

1 Ответ

0 голосов
/ 22 декабря 2018

Когда меню устанавливается в QPushButton, событие mousePressEvent больше не достигает QPushButton, но перехватывается QMenu, поэтому сигнал щелчка не генерируется.

Одно решениеэто установить QMenu по умолчанию и использовать сигнал aboutToShow для вызова set_menu, который добавит QAction s.

С другой стороны, они одинаковы, потому что нажатие не выдается и, следовательно, set_menu невызывается, и даже если вы вызываете set_menu, как я установил, лучше использовать повторно, чем создавать, поэтому в этом случае я исключаю предыдущие QActions с помощью метода clear.

from functools import partial
from PyQt4 import QtCore, QtGui

class MyWin(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyWin, self).__init__()
        central_widget = QtGui.QWidget()
        self.setCentralWidget(central_widget)
        vlay = QtGui.QVBoxLayout(central_widget)
        hlay = QtGui.QHBoxLayout()
        vlay.addLayout(hlay)
        vlay.addStretch()

        self.add_button = QtGui.QToolButton()
        self.tab_bar = QtGui.QTabBar(self)
        self.add_button.setIcon(QtGui.QIcon('add.png'))

        self.qmenu = QtGui.QMenu(self.add_button)
        self.add_button.setMenu(self.qmenu)
        self.add_button.setPopupMode(QtGui.QToolButton.InstantPopup)

        self.qmenu.aboutToShow.connect(self.set_menu)

        self.tab_bar.setTabButton(
            0,
            QtGui.QTabBar.ButtonPosition.RightSide,
            self.add_button
        )
        hlay.addWidget(self.add_button)
        hlay.addWidget(self.tab_bar)

    @QtCore.pyqtSlot()
    def set_menu(self):
        with open('/Desktop/item_file.txt') as f:
            menu_options = f.read().splitlines()
            self.qmenu.clear()
            for opt in menu_options:
                self.qmenu.addAction(opt, partial(self.set_new_tab, opt))

    def set_new_tab(self, opt):
        self.tab_bar.addTab(opt)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    w = MyWin()
    w.show()
    sys.exit(app.exec_())
...