QToolButton clicked 信号只被调用一次

QToolButton clicked signal is only called once

我已将 QMenu 附加到 QToolButton,其中菜单未正确反映。

我正在通过读取 .txt 文件来填充我的 QMenu。菜单在第一个 运行 上显示正确的项目,但是如果我在 .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)

QPushButton中建立Menu时,mousePressEvent事件不再到达QPushButton,而是被QMenu截获,所以点击信号不发射。

一种解决方案是默认设置 QMenu 并使用 aboutToShow 信号调用 set_menu,这将添加 QActions。

另一方面,它们是相同的,因为没有发出 clicked,因此 set_menu 没有被调用,即使你像我已经建立的那样调用 set_menu 重用比创建更好所以在这种情况下,我用 clear 方法消除了之前的 QActions。

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_())