下面的代码有点长,在pip安装PyQt5后运行:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QLabel
from PyQt5.QtCore import pyqtSignal
class MyPushButton(QPushButton):
self_emit_toggle_signal = pyqtSignal(list)
def __init__(self, text):
super().__init__(text)
self.emit_self_toggle = False
self.toggled.connect(self.when_toggled)
def when_toggled(self, checked):
if self.emit_self_toggle:
self.self_emit_toggle_signal.emit([self, checked])
class ButtonWidget(QWidget):
def __init__(self):
super().__init__()
self.buttons = []
self.checked_buttons = []
self.init_ui()
def init_ui(self):
self.setWindowTitle("Widget with 10 Push Buttons")
# Create 10 push buttons
for i in range(0, 10):
button = MyPushButton(f"Button {i}")
self.buttons.append(button)
# Add buttons to the layout
layout = QVBoxLayout()
self.label = QLabel("Game not started.")
layout.addWidget(self.label)
self.start_button = QPushButton("Start")
layout.addWidget(self.start_button)
self.clear_button = QPushButton("Clear")
layout.addWidget(self.clear_button)
for button in self.buttons:
layout.addWidget(button)
self.setLayout(layout)
#Callbacks:
self.start_button.clicked.connect(self.start_game)
self.clear_button.clicked.connect(self.clear_game)
self.show()
def start_game(self):
self.label.setText("Game started.")
for button in self.buttons:
button.setCheckable(True)
button.emit_self_toggle = True
button.self_emit_toggle_signal.connect(self.upon_toggle)
def upon_toggle(self, list_button_checked):
button, checked = list_button_checked[0], list_button_checked[1]
if checked:
self.checked_buttons.append(button)
else:
self.checked_buttons.remove(button)
self.update_label()
def update_label(self):
for button in self.buttons:
if button in self.checked_buttons:
index = self.buttons.index(button)
checked_index = self.checked_buttons.index(button)
button.setText(str(checked_index + 1) + " :" + f"Button {index}") #line (1)
else:
index = self.buttons.index(button)
button.setText(f"Button {index}")
def clear_game(self):
self.label.setText("Game not started.")
self.checked_buttons.clear()
for button in self.buttons:
button.emit_self_toggle = False
button.setCheckable(False)
button.setChecked(False)
button.self_emit_toggle_signal.disconnect(self.upon_toggle)
self.update_label()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ButtonWidget()
sys.exit(app.exec_())
字符串
它给出了以下内容:
的数据
上面的代码做了什么,用文字来说,如下所示:在用户点击“开始”之后,用户将能够点击按钮。用户点击的顺序将直接反映在按钮的标签上。如果一个按钮被点击,用户再次点击它,那么点击被取消,程序将该按钮视为以前从未点击过。单击“清除”将初始化程序。从程序上讲,代码保存选中按钮的列表,在用户单击时更新列表,并相应地重写每个按钮上的文本。
例如:如果用户点击“开始”,然后按顺序按钮1,2,3,4,5,1,它将显示以下内容:
的
问题:
1.现在,我通过直接更改按钮上的文本来反映用户点击的顺序(参见第(1)行)。有没有可能修改上面的代码,使顺序仍然被反映出来,按钮上的文本完全不变?最优选的结果将是一些彩色数字“浮动”在按钮的左手侧。
1.(可选)是否有办法完全避免使用检查状态?如果没有,我至少可以隐藏检查状态吗?
下面是一个演示,当1和2都达到时,我的意思是什么,点击与上面的例子完全相同:
的
注意事项:
所提供的代码旨在作为演示。您可以随意以任何方式更改所提供的代码,包括完全重写它。没有必要担心性能。在我的实际项目中,按钮的数量肯定会小于15。
1条答案
按热度按时间hc8w905p1#
由于您只想知道按钮被点击的顺序,因此使用按钮的选中状态实际上是没有意义的,特别是因为您不希望事件显示它。只需连接到标准
clicked
信号即可。事实上,逻辑很简单;单击按钮时,则:
如果您想在按钮之外显示数字,那么为每个按钮使用“兄弟”标签。
在下面的代码修改中,我为标签和按钮使用了内部网格布局,它们将被添加到它们各自的列表中。
然后,要获取被单击并触发connected函数的按钮,只需使用所有QObjects的
sender()
函数,该函数返回发出信号的对象。字符串