0

我有一个QMainWindow, 里面有一个QMenu,QLineEdit和一个QPushButton

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

像这样

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

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

下面是我的代码:

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

我希望能够playsound()根据在菜单栏中选中的 QAction 来更改值。在选中一个 QAction 时,应取消选中其他 QAction。

4

1 回答 1

1

这就是行动小组发挥作用的地方。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.splaysound(self.soundGroup.checkedAction().data(), False)

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

于 2021-07-02T14:05:39.847 回答