我想根据 QMenu 中选中的动作更改每次按下按钮时播放的声音
I want to change the sound that plays every time a button is pressed depending on a checked actiion in a QMenu
我有一个QMainWindow
,里面有一个QMenu
,QLineEdit
,还有一个QPushButton
。
每次单击按钮时,它都会播放声音,然后将文本添加到 QLineEdit。
在我的 QMenu 中,用户必须能够通过选中它来选择播放的声音。
我试图通过在每次检查 QAction 时更改 MainWindow class 中的变量 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, 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
allows for mutually exclusive actions. It also provides convenient access to the selected action through the checkedAction 方法。
- 创建一个
QActionGroup
对象(例如 self.soundGroup = QActionGroup(self)
)
- 以群组为父项创建您的操作(例如
self.sound1 = QAction(self.soundGroup)
)
- 对于你的每一个动作,将它们对应的声音设置为它们的数据,例如
self.sound1.setData('sound1.mp3')
- 确保操作组是独占的(我相信这是默认设置,但您可以使用
self.soundGroup.setExclusive(True)
)
- 使用
self.soundGroup.checkedAction()
代替self.view.s
获取选中的动作(选择的声音):playsound(self.soundGroup.checkedAction().data(), False)
您不再需要在 self.view.s
的操作和更新之间进行任何连接。只需删除所有这些。
我有一个QMainWindow
,里面有一个QMenu
,QLineEdit
,还有一个QPushButton
。
每次单击按钮时,它都会播放声音,然后将文本添加到 QLineEdit。 在我的 QMenu 中,用户必须能够通过选中它来选择播放的声音。
我试图通过在每次检查 QAction 时更改 MainWindow class 中的变量 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, 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
allows for mutually exclusive actions. It also provides convenient access to the selected action through the checkedAction 方法。
- 创建一个
QActionGroup
对象(例如self.soundGroup = QActionGroup(self)
) - 以群组为父项创建您的操作(例如
self.sound1 = QAction(self.soundGroup)
) - 对于你的每一个动作,将它们对应的声音设置为它们的数据,例如
self.sound1.setData('sound1.mp3')
- 确保操作组是独占的(我相信这是默认设置,但您可以使用
self.soundGroup.setExclusive(True)
) - 使用
self.soundGroup.checkedAction()
代替self.view.s
获取选中的动作(选择的声音):playsound(self.soundGroup.checkedAction().data(), False)
您不再需要在 self.view.s
的操作和更新之间进行任何连接。只需删除所有这些。