微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我想根据 QMenu 中选中的动作更改每次按下按钮时播放的声音

如何解决我想根据 QMenu 中选中的动作更改每次按下按钮时播放的声音

我有一个 QMainWindow,里面有一个 QMenuQLineEdit一个 QPushButton

每次我单击按钮时,它都会播放声音,然后将文本添加到 QLineEdit。 在我的 QMenu 中,用户必须能够通过检查来选择播放哪种声音。

Like this

我试图通过每次检查 QAction 时更改 MainWindow 类中的变量 self.s 来实现这一点,同时未选中其他 QAction。所以在我的 playsound() 中,我只是将 self.view.s 作为参数。

不过好像只读了原音self.view.s,也就是第一个音。我改变 self.view.s 的信号不起作用。此外,其他 QActions 并没有像我希望的那样取消选中。

下面是我的代码

import sys
from functools import partial
from playsound import playsound
from threading import Thread
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.buttons = {}
        self.setwindowTitle("Try")

        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        self.lay = QVBoxLayout(central_widget)
        self.lineedit()

        button = {"hey! ": (0,0)}

        page = QWidget()
        layout = qgridLayout(page)
        for btnText,pos in button.items():
            self.buttons[btnText] = QPushButton(btnText)
            layout.addWidget(self.buttons[btnText],*pos)

        self.lay.addWidget(page)
        self.music()

    def music(self):
        self.s = 'sound1.mp3'
        
        self.x = 'sound1.mp3'
        self.y = 'sound2.mp3'
        self.z = 'disable.mp3'

    def lineedit(self):
        self.le = QLineEdit()
        self.le.setFixedHeight(35)
        self.lay.addWidget(self.le)

    def set_lineedit(self,text):
        self.le.setText(text)
        self.le.setFocus()

    def line(self):
        return self.le.text()


class Menu:

    def __init__(self,MainWindow):

        super().__init__()

        self.view = MainWindow
        self.menuBar()
        #self.actionSignals()

    def menuBar(self):
        self.menuBar = QMenuBar()
        self.view.setMenuBar(self.menuBar)

        self.menu = QMenu(self.menuBar)
        self.menu.setTitle('Menu')

        self.sounds = QMenu(self.menu)
        self.sounds.setTitle('Select Sound')

        self.sound1 = QAction(self.menuBar)
        self.sound2 = QAction(self.menuBar)
        self.disable = QAction(self.menuBar)

        self.mute = QAction(self.menuBar)
        self.mute.setText('Mute Background')
        self.mute.setCheckable(True)
        self.mute.setChecked(False)

        self.sound1.setText('Sound 1')
        self.sound1.setCheckable(True)
        self.sound1.setChecked(True)
        self.sound2.setText('Sound 2')
        self.sound2.setCheckable(True)
        self.sound2.setChecked(False)
        self.disable.setText('disable Sound')
        self.disable.setCheckable(True)
        self.disable.setChecked(False)

        self.sounds.addAction(self.sound1)
        self.sounds.addAction(self.sound2)
        self.sounds.addAction(self.disable)


        self.menuBar.addAction(self.menu.menuAction())
        self.menu.addAction(self.mute)
        self.menu.addAction(self.sounds.menuAction())

    def menu_signals(self):
        
        self.sound1.triggered.connect(self.sound_1)
        self.sound2.triggered.connect(self.sound_2)
        self.disable.triggered.connect(self.disabled)

    def sound_1(self,checked):
        
        if checked:
            self.sound2.setChecked(False)
            self.disable.setChecked(False)
            self.view.s = self.view.x

        else:
            self.sound1.setChecked(True)


    def sound_2(self,checked):

        if checked:
            self.sound1.setChecked(False)
            self.disable.setChecked(False)
            self.view.s = self.view.y

        else:
            self.sound2.setChecked(True)

    def disabled(self,checked):
        
        if checked:
            self.sound2.setChecked(False)
            self.sound1.setChecked(False)
            self.view.s = self.view.z

        else:
            self.sound1.setChecked(True)

class Controller:

    def __init__(self,MainWindow):

        self.view = MainWindow
        self.connectSignals()

    def background(self):
        while True:
            playsound('background.mp3')

    def playsound(self):
        playsound(self.view.s,False)

    def buildExpression(self,sub_exp):

        expression = self.view.line() + sub_exp
        self.view.set_lineedit(expression)

    def connectSignals(self):

        for btnText,btn in self.view.buttons.items():
            self.view.buttons[btnText].clicked.connect(self.playsound)
            self.view.buttons[btnText].clicked.connect(partial(self.buildExpression,btnText))

app = QApplication(sys.argv)
w = MainWindow()
x = Controller(w)
Thread(target = x.background,daemon = True).start()
m = Menu(w)
w.show()
app.exec()

我希望能够根据在菜单栏中选中的 QAction 来更改 playsound() 内的值。当一个 QAction 被选中时,另一个 QAction 应该不被选中。

解决方法

这是行动小组发挥作用的地方。 QActionGroup 允许互斥操作。它还可以通过 checkedAction 方法方便地访问所选操作。

  1. 创建一个 QActionGroup 对象(例如 self.soundGroup = QActionGroup(self)
  2. 以组为父级创建您的操作(例如 self.sound1 = QAction(self.soundGroup)
  3. 对于你的每一个动作,将它们对应的声音设置为它们的数据,例如self.sound1.setData('sound1.mp3')
  4. 确保操作组是独占的(我相信这是默认设置,但您可以使用 self.soundGroup.setExclusive(True)
  5. 使用 self.soundGroup.checkedAction() 代替 self.view.s 获取选中的动作(选定的声音):playsound(self.soundGroup.checkedAction().data(),False)

您不再需要在操作和更新 self.view.s 之间进行任何连线。只需删除所有这些。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。