python pyqt5 替换 QToolButton 中的 QMenu

python pyqt5 Replace QMenu in QToolButton

文件:ui.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'ui.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)
        self.general_deck_mute_toolbutton = QtWidgets.QToolButton(Dialog)
        self.general_deck_mute_toolbutton.setGeometry(QtCore.QRect(60, 40, 101, 45))
        self.general_deck_mute_toolbutton.setMinimumSize(QtCore.QSize(45, 45))
        self.general_deck_mute_toolbutton.setStyleSheet("")
        self.general_deck_mute_toolbutton.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup)
        self.general_deck_mute_toolbutton.setAutoRaise(False)
        self.general_deck_mute_toolbutton.setObjectName("general_deck_mute_toolbutton")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.general_deck_mute_toolbutton.setText(_translate("Dialog", "QToolButton"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

文件:main.py

from PyQt5 import QtCore, QtGui, QtWidgets
from ui import Ui_Dialog
import sys

class Main_Program:
    def __init__(self):
        
        app = QtWidgets.QApplication(sys.argv)
        self.Dialog = QtWidgets.QDialog()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self.Dialog)
        self.Dialog.show()
        
        self.deck_1 = {
            "mute":False
        }
        
        self.deck_2 = {
            "mute":False
        }
        
        self.music_clip_deck = {
            "mute":False
        }
        
        self.make_qtoolbutton_menu()
        
        
        sys.exit(app.exec_())
    
    def make_qtoolbutton_menu(self):
        self.mute_toolbutton_menu = QtWidgets.QMenu()
        try:
            self.mute_deck_1_action.disconnect()
        except:
            pass
        self.mute_deck_1_action = QtWidgets.QAction(self.Dialog)
        if self.deck_1["mute"]==0 or self.deck_1["mute"]==False:
            self.mute_deck_1_action.setText("Απενεργοποίηση σίγασης deck 1")
        else:
            self.mute_deck_1_action.setText("Ενεργοποίηση σίγασης στο deck 1")
        self.mute_toolbutton_menu.addAction(self.mute_deck_1_action)
        self.mute_deck_1_action.triggered.connect(self.mute_or_unmute_deck_1)
        
        try:
            self.mute_deck_2_action.disconnect()
        except:
            pass
        self.mute_deck_2_action = QtWidgets.QAction(self.Dialog)
        if self.deck_2["mute"]==0 or self.deck_2["mute"]==False:
            self.mute_deck_2_action.setText("Απενεργοποίηση σίγασης deck 2")
        else:
            self.mute_deck_2_action.setText("Ενεργοποίηση σίγασης στο deck 2")
        self.mute_toolbutton_menu.addAction(self.mute_deck_2_action)
        self.mute_deck_2_action.triggered.connect(self.mute_or_unmute_deck_2)
        
        try:
            self.mute_music_clip_deck_action.disconnect()
        except:
            pass
        self.mute_music_clip_deck_action = QtWidgets.QAction(self.Dialog)
        if self.music_clip_deck["mute"]==0 or self.music_clip_deck["mute"]==False:
            self.mute_music_clip_deck_action.setText("Απενεργοποίηση σίγασης music clip deck")
        else:
            self.mute_music_clip_deck_action.setText("Ενεργοποίηση σίγασης στο music clip deck")
        self.mute_toolbutton_menu.addAction(self.mute_music_clip_deck_action)
        self.mute_music_clip_deck_action.triggered.connect(self.mute_or_unmute_music_clip_deck)
        
        try:
            self.ui.general_deck_mute_toolbutton.disconnect()
        except:
            pass
        self.ui.general_deck_mute_toolbutton.setMenu(self.mute_toolbutton_menu)
        #self..ui.general_deck_mute_toolbutton.clicked.connect(self.mute_menu_clicked)

    
    def mute_or_unmute_deck_1(self):
        self.deck_1["mute"] = not self.deck_1["mute"]
        self.make_qtoolbutton_menu()
        
    def mute_or_unmute_deck_2(self):
        self.deck_2["mute"] = not self.deck_2["mute"]
        self.make_qtoolbutton_menu()
        
    def mute_or_unmute_music_clip_deck(self):
        self.music_clip_deck["mute"] = not self.music_clip_deck["mute"]
        self.make_qtoolbutton_menu()
        
if __name__ == "__main__":
    program = Main_Program()

重现问题 运行 python main.py 然后单击菜单操作(从向下箭头)。

屏幕中出现此错误消息:

QObject::disconnect: Unexpected nullptr parameter
QObject::disconnect: Unexpected nullptr parameter
QObject::disconnect: Unexpected nullptr parameter
QObject::disconnect: Unexpected nullptr parameter
QObject: shared QObject was deleted directly. The program is malformed and may crash.

我认为没有必要创建 QMenu 和 QAction,连接和断开它们只是为了更改文本。创建一个更新文本的方法就足够了:

class Main_Program:
    def __init__(self):

        app = QtWidgets.QApplication(sys.argv)
        self.Dialog = QtWidgets.QDialog()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self.Dialog)
        self.Dialog.show()

        self.deck_1 = {"mute": False}

        self.deck_2 = {"mute": False}

        self.music_clip_deck = {"mute": False}

        self.make_qtoolbutton_menu()
        self.update_text_qtoolbutton_menu()

        sys.exit(app.exec_())

    def make_qtoolbutton_menu(self):
        self.mute_toolbutton_menu = QtWidgets.QMenu()

        self.mute_deck_1_action = QtWidgets.QAction(self.Dialog)
        self.mute_deck_1_action.triggered.connect(self.mute_or_unmute_deck_1)
        self.mute_toolbutton_menu.addAction(self.mute_deck_1_action)

        self.mute_deck_2_action = QtWidgets.QAction(self.Dialog)
        self.mute_deck_2_action.triggered.connect(self.mute_or_unmute_deck_2)
        self.mute_toolbutton_menu.addAction(self.mute_deck_2_action)

        self.mute_music_clip_deck_action = QtWidgets.QAction(self.Dialog)
        self.mute_music_clip_deck_action.triggered.connect(
            self.mute_or_unmute_music_clip_deck
        )
        self.mute_toolbutton_menu.addAction(self.mute_music_clip_deck_action)
        self.ui.general_deck_mute_toolbutton.setMenu(self.mute_toolbutton_menu)

    def update_text_qtoolbutton_menu(self):
        self.mute_deck_1_action.setText(
            "Ενεργοποίηση σίγασης στο deck 1"
            if self.deck_1["mute"]
            else "Απενεργοποίηση σίγασης deck 1"
        )
        self.mute_deck_2_action.setText(
            "Ενεργοποίηση σίγασης στο deck 2"
            if self.deck_2["mute"]
            else "Απενεργοποίηση σίγασης deck 2"
        )
        self.mute_music_clip_deck_action.setText(
            "Ενεργοποίηση σίγασης στο music clip deck"
            if self.music_clip_deck["mute"]
            else "Απενεργοποίηση σίγασης music clip deck"
        )

    def mute_or_unmute_deck_1(self):
        self.deck_1["mute"] = not self.deck_1["mute"]
        self.update_text_qtoolbutton_menu()

    def mute_or_unmute_deck_2(self):
        self.deck_2["mute"] = not self.deck_2["mute"]
        self.update_text_qtoolbutton_menu()

    def mute_or_unmute_music_clip_deck(self):
        self.music_clip_deck["mute"] = not self.music_clip_deck["mute"]
        self.update_text_qtoolbutton_menu()