我正在使用PyQt5制作一个GUI,此GUI在页面顶部有几个按钮,可根据选择更改较低StackedWidget的索引。单击该按钮时,所选按钮会将所选按钮的样式表更改为selected_style
,但将所有其他样式更改为unselected_style
。我读到最简单,最通用的方法是每行添加单个动作。但这已经变得非常多余,最终导致行数过多。目前,这是由单行实现的,例如:
self.pshBtn_1.clicked.connect(lambda: self.stckWdgt.setCurrentIndex(0))
self.pshBtn_1.clicked.connect(lambda: self.pshBtn_1.setStyleSheet(selected)
self.pshBtn_1.clicked.connect(lambda: self.pshBtn_2.setStyleSheet(unselected)
self.pshBtn_1.clicked.connect(lambda: self.pshBtn_3.setStyleSheet(unselected)
self.pshBtn_2.clicked.connect(lambda: self.stckWdgt.setCurrentIndex(1))
self.pshBtn_2.clicked.connect(lambda: self.pshBtn_2.setStyleSheet(selected)
self.pshBtn_2.clicked.connect(lambda: self.pshBtn_1.setStyleSheet(unselected)
self.pshBtn_2.clicked.connect(lambda: self.pshBtn_3.setStyleSheet(unselected)
# And so on, and so on, and so on
我试图遍历self
下函数中的按钮名称列表,但是我一直以NameErrors
结尾。像这样:
self.pshBtn_1.clicked.connect(self.set_btn_style, pshBtn_1)
self.pshBtn_2.clicked.connect(self.set_btn_style, pshBtn_2)
self.pshBtn_3.clicked.connect(self.set_btn_style, pshBtn_3)
btn_dict = {pshBtn_1 : 0, pshBtn_2: 1, pshBtn_3: 2} #Button Name, Stacked Widget Index
def set_btn_style(self, var_name):
for i, j in btn_dict:
btn_name = i
idx = j
if btn_name == var_name:
self.keyname.setStyleSheet(button_selected)
self.stckWdgt.setCurrentIndex(idx))
else:
self.btn.setStyleSheet(button_unselected)
我猜这里最大的问题是如何让几个按钮或GUI动作使用一个函数,但是将特定的tableWidget,stackWidget等作为参数传递,所以我不必重复某些函数10我想使用该功能的每个按钮的次数。谢谢。
答案 0 :(得分:2)
最简单的方法是启用QPushButtons的checkable属性,然后将其用作Qt样式表中的过滤器,而不是每次按下按钮时都设置样式表。要更改页面并仅选择一个页面,请使用QButtonGroup。
from PyQt5 import QtCore, QtWidgets
QSS = """
Button {
background-color: #00ff00;
}
Button:checked {
background-color: #ff0000;
}
"""
class Button(QtWidgets.QPushButton):
pass
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
page1 = QtWidgets.QLabel("page1", alignment=QtCore.Qt.AlignCenter)
page2 = QtWidgets.QLabel("page2", alignment=QtCore.Qt.AlignCenter)
page3 = QtWidgets.QLabel("page3", alignment=QtCore.Qt.AlignCenter)
options = ["Page1", "Page2", "Page3"]
stackedwidget = QtWidgets.QStackedWidget()
hlay = QtWidgets.QHBoxLayout()
group = QtWidgets.QButtonGroup(self)
group.buttonClicked[int].connect(stackedwidget.setCurrentIndex)
for i, (option, widget) in enumerate(zip(options, (page1, page2, page3))):
button = Button(text=option, checkable=True)
ix = stackedwidget.addWidget(widget)
group.addButton(button, ix)
hlay.addWidget(button)
if i == 0:
button.setChecked(True)
vbox = QtWidgets.QVBoxLayout(self)
vbox.addLayout(hlay)
vbox.addWidget(stackedwidget)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle("fusion")
app.setStyleSheet(QSS)
w = Widget()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
答案 1 :(得分:1)
我经常遇到这个问题,我想将小部件名称传递给另一个函数。我可以通过制作一个嵌套的字典来解决此问题,该字典将一个项目链接到我想传递的小部件名称。该函数在主类的for循环中调用。在函数中,我使用self.sender()
和sending_button.objectName()
来获取用于启动函数的项目的名称。
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Ui_MainWindow, self).__init__(parent)
self.setupUi(self)
# ^^ Up here would be a bunch of buttons I want to do something with
# Make a nested Dictionary to hold the string name of button,
# the actual widget name, and the stacked widget index it corresponds to.
self.btn_change_sel = {'pushButton_1': {self.pushButton_1: 0},
'pushButton_2': {self.pushButton_2: 1} }
# if any button is pressed, launch function.
for item in self.btn_change_sel.keys():
for button in self.btn_change_sel[item].keys():
button.clicked.connect(self.btn_style_change)
def btn_style_change(self):
sending_button = self.sender()
check_sender = str(sending_button.objectName()) # Get the string name of sender button
for sender_name in self.btn_change_sel.keys(): # Get string name to match
# If the clicked button matches the string value, do some stuff
if check_sender == sender_name:
for btn_item in self.btn_change_sel[sender_name].keys():
btn_item.setStyleSheet(self.button_selected)
for stack_idx in self.btn_change_sel[sender_name].values():
self.stackedWidget_all.setCurrentIndex(stack_idx)
# Do something with all other buttons not selected, change to a different style
if check_sender != sender_name:
for btn_item2 in self.btn_change_sel[sender_name].keys():
btn_item2.setStyleSheet(self.button_unselected)
因此,在此示例中,如果单击的按钮匹配,它将更改样式表并选择与按钮单击相对应的stackedWidget。所有其他人都会收到未选中的样式。这使显示的小部件按钮变得不同,因此您可以轻松分辨出您所在的小部件页面。