問題描述
所以目前我正在 PyQt5 中創建數獨.所以,到目前為止,我有 Board.py,它只是生成新的板.目前我正在研究 Play.py,它應該能夠點擊空白方塊并能夠通過按下鍵盤按鈕(按鍵)來更改它.在 Play.py 中,我已經完成了所有操作 - 所有數字都放入了一塊板上,我可以單擊按鈕并啟動按鍵.但是,按照我的編碼方式,所有按鈕都存儲在一個列表中(我這樣做是因為我希望代碼看起來干凈)并且它只更新最后一個按鈕.我希望它更新最近單擊的按鈕,而不是更新最后一個按鈕.
So currently I am creating Sudoku in PyQt5. So, far I have Board.py which just generates new boards. Currently I am working on Play.py, which should be able to click on empty squares and be able to change it with the press of a keyboard button(keypress). In Play.py I have finished everything - All the numbers are put into a board and I am able to click on buttons and it initiates a keypress. But, the way I coded it, all the buttons are stored into a list (I did this because I wanted the code to look clean) and it only updates the last button. Instead of it updating the last button, I would like it to update the button that was most recently clicked.
我已經嘗試了很多東西,但我目前將其縮小到的是在所有按鈕(all_buttons)列表中找到按鈕的位置并從那里做一些事情,但我不確定.那么,如何才能將按鍵按下并將其放入最近按下的按鈕中?
I have tried many things but what I have narrowed it down to currently is to find the position of the button in the list of all buttons(all_buttons) and do something from there but I'm not sure. So, how would I be able to take the key press and put it into the button that was recently pressed?
這里是 Board.py.它只是生成了不需要查看的新板.
Here is Board.py. It just generates new boards it is unnecessary to look at.
import random
import numpy as np
# populates a row in random spaces
def populate():
row = [0] * 9
num_in_box = random.randint(3, 6)
while True:
spot = random.randint(0, 8)
r = random.randint(1, 9)
if r not in row:
row[spot] = r
if row.count(0) == (9 - num_in_box):
break
return row
# populates a grid in random spaces - has duplicates in column, row and box
mapped = list()
for x in range(9): mapped.append(populate())
# checks every number in column and row and returns numbers in list
def col_row_nums(array, row, col):
check_col = [j for j in array[:, col] if j != 0]
check_row = [i for i in array[row] if i != 0]
if array[row][col] in check_col:
check_col.remove(array[row][col])
return check_col + check_row
# checks every number box and returns numbers in list
def box_nums(array, box_row):
reshaped_box = np.reshape(array, (27, 3))
list_boxes_in_rows = list()
for a in range(3):
for b in range(3):
for c in range(3):
p2 = list(np.reshape((reshaped_box[c::3]), (3, 9)))
for d in range(3): list_boxes_in_rows.append(p2[a])
array_boxes_in_rows = np.array(list_boxes_in_rows)
return [k for k in array_boxes_in_rows[box_row] if k != 0]
# removes any duplicates so each column, row and box all have only one set of numbers 1 - 9
def finalize_board():
box_rows_num = -1
for x in range(9):
for y in range(9):
box_rows_num += 1
arr = np.array(mapped)
possible_nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
col_row_duplicates = list()
box_duplicates = list()
used_nums = set(col_row_nums(arr, x, y)) | set(box_nums(arr, box_rows_num))
for w in used_nums:
col_row_count = col_row_nums(arr, x, y).count(w)
box_count = box_nums(arr, box_rows_num).count(w)
if col_row_count > 1: col_row_duplicates.append(w)
if box_count > 1: box_duplicates.append(w)
if mapped[x][y] in col_row_duplicates or mapped[x][y] in box_duplicates:
remaining_nums = list(set(possible_nums) - set(used_nums))
if len(remaining_nums) > 0: mapped[x][y] = random.choice(remaining_nums)
return mapped
接下來是 Play.Py.
Next is Play.Py.
import sys
from pynput import keyboard
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
import Board
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# -------------------------------------------------------------------------------------------
all_buttons = list()
layout = qtw.QGridLayout()
layout.setSpacing(0)
board = Board.finalize_board()
y_num = -1
for x, rows in enumerate(board):
for y, cell in enumerate(rows):
y += 1
if cell == 0: cell = ' '
button = qtw.QPushButton(str(cell), self)
button.setFixedHeight(100)
button.setFixedWidth(100)
layout.addWidget(button, x, y)
if cell == ' ':
button.clicked.connect(lambda: pressed())
button.setStyleSheet('QPushButton {background-color: #e3efff; color: black;}')
else:
button.setEnabled(False)
button.setStyleSheet('QPushButton {background-color: #ebebeb; color: black;}')
all_buttons.append(button)
def pressed():
with keyboard.Events() as events:
# maybe - ?? HOW TO RETURN POSITION OF BUTTON IN ALL_BUTTONS
event = events.get(1e6)
x = event.key
print(str(x))
button.setText(str(x))
self.setLayout(layout)
# -------------------------------------------------------------------------------------------
self.show()
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
推薦答案
你快到了.使用 keyPressEvent
點擊這里.
import sys
from PyQt5.QtWidgets import (QApplication, QWidget)
from PyQt5.Qt import Qt
class MainWindow(QWidget):
def __init__(self):
super().__init__()
def keyPressEvent(self, event):
print(chr(event.key()))
def test_method(self):
print('Space key pressed')
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = MainWindow()
demo.show()
sys.exit(app.exec_())
event.key()
將始終返回一個整數.您可以使用內置的 chr(int)
函數來獲取密鑰,問題是我們無法識別字母和數字以外的密鑰.如果您還想要其他鍵,請使用條件.
event.key()
will always return an integer. You can use the built-in chr(int)
function to get the key, the problem is we can't identify keys other than alphabets and numbers. If you want other keys as well, use conditions.
def keyPressEvent(self, event):
if event.key() == Qt.Key_Space:
print("Space pressed")
# Qt.Key_Shift for shift key, Qt.Key_Control for Ctrl key.
這是最終代碼:閱讀edit2
import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5.QtCore import pyqtSlot
from PyQt5 import QtGui as qtg
import Board
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# -------------------------------------------------------------------------------------------
all_buttons = list()
layout = qtw.QGridLayout(self)
layout.setSpacing(0)
board = Board.finalize_board()
y_num = -1
for x, rows in enumerate(board):
for y, cell in enumerate(rows):
y += 1
if cell == 0: cell = ' '
button = qtw.QPushButton(str(cell), self)
button.setFixedHeight(100)
button.setFixedWidth(100)
layout.addWidget(button, x, y)
if cell == ' ':
button.setCursor(qtc.Qt.PointingHandCursor)
button.mousePressEvent = lambda event: self.mousePressEvent(event)
button.setStyleSheet('QPushButton {background-color: #e3efff; color: black;}')
else:
button.setEnabled(False)
button.setStyleSheet('QPushButton {background-color: #ebebeb; color: black;}')
all_buttons.append(button)
self.last_clicked = ''
self.setLayout(layout)
# -------------------------------------------------------------------------------------------
self.show()
def keyPressEvent(self, event):
k = (chr(event.key()))
self.last_clicked.setText(k)
self.last_clicked.setStyleSheet("background-color: #e3efff; color: black;")
def mousePressEvent(self, event):
widget = self.childAt(event.pos())
widget.setStyleSheet("background-color: #e3efff; color: black; border: 1px solid red")
print(widget.pos())
self.last_clicked = widget
return qtw.QWidget.mousePressEvent(self, event)
# -------------------------------------------------------------------------------------------
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
現在,當您按下某個鍵時,它會更新最近單擊按鈕的文本.您可能想添加一些嘗試,除了 keyPressEvent
和 setText 函數
Now when you press a key, it updates the text of the recently clicked button. You might want to add some try except to the keyPressEvent
and setText function
編輯 2:我不完全知道為什么第一個按鈕被選中,我猜 mousePressEvent
有問題.它首先返回第一個小部件,然后返回實際單擊的按鈕.我調整了一些東西,現在可以正常工作了.
EDIT 2:
I don't exactly know why the first button gets selected, I'm guessing something's wrong with the mousePressEvent
. It first returns the first widget and then the actual button that was clicked. I tweaked a few things and it now works fine.
我改變的東西:
我創建了一個新列表
self.available_buttons
.它包含所有空的/可點擊的按鈕.
I created a new list
self.available_buttons
. It contains all the empty/clickable buttons.
只要按下一個空按鈕,代碼就會遍歷列表并搜索 last_clicked
小部件.如果找到 last_clicked
小部件,它會突出顯示該按鈕并將所有其他按鈕更改為正常(無邊框顏色).
Whenever an empty button is pressed, the code goes through the list and searches for last_clicked
widget. If the last_clicked
widget is found, it highlights the button and changes all other buttons to normal(no border color).
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# -------------------------------------------------------------------------------------------
all_buttons = list() # contains all buttons
self.available_buttons = list() # contains clickable buttons
layout = qtw.QGridLayout(self)
layout.setSpacing(0)
board = Board.finalize_board()
y_num = -1
for x, rows in enumerate(board):
for y, cell in enumerate(rows):
y += 1
if cell == 0: cell = ' '
button = qtw.QPushButton(str(cell), self)
button.setFixedHeight(100)
button.setFixedWidth(100)
layout.addWidget(button, x, y)
if cell == ' ':
button.setCursor(qtc.Qt.PointingHandCursor)
button.mousePressEvent = lambda event: self.mousePressEvent(event)
button.setStyleSheet('QPushButton {background-color: #e3efff; color: black;}')
self.available_buttons.append(button) # appends empty buttons to the list
else:
button.setEnabled(False)
button.setStyleSheet('QPushButton {background-color: #ebebeb; color: black;}')
all_buttons.append(button)
self.last_clicked = ''
self.setLayout(layout)
self.show()
# -------------------------------------------------------------------------------------------
def keyPressEvent(self, event):
k = (chr(event.key()))
self.last_clicked.setText(k)
self.last_clicked.setStyleSheet("background-color: #e3efff; color: black;")
def mousePressEvent(self, event):
widget = self.childAt(event.pos())
self.last_clicked = widget
for button in self.available_buttons: #searches for clicked button
if widget == button:
button.setStyleSheet("background-color: #e3efff; color: black; border: 1px solid red") # adds border to clicked button
else:
button.setStyleSheet("background-color: #e3efff; color: black;") # all the other buttons go back to their normal state
return qtw.QWidget.mousePressEvent(self, event)
# -------------------------------------------------------------------------------------------
這篇關于使用按鍵單擊時如何更改pyqt5中的按鈕文本的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!