pyqt5 运行 慢
pyqt5 is running slow
所以我的程序是一个数独,至此,我已经完成了生成棋盘的代码。我正在尝试将其实现到 pyqt5 中。我通过使按钮对应于数独板中的每个数字(因此有 81 个按钮)来完成此操作。我有一台能够以高帧率玩 运行 三 A 游戏的电脑(如果这很重要的话)。可能是什么问题?我把我的代码放在下面。
import random
import numpy as np
import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
# 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]
# Basically goes through each number and 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
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# -------------------------------------------------------------------------------------------
all_buttons = list()
layout = qtw.QGridLayout()
for x in range(9):
for y in range(9):
if finalize_board()[x][y] == 0: finalize_board()[x][y] = ' '
all_buttons.append(layout.addWidget(qtw.QPushButton(str(finalize_board()[x][y])), x, y))
self.setLayout(layout)
# -------------------------------------------------------------------------------------------
self.show()
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
问题是你正在为每个按钮执行 finalize_board 函数,所以如果函数需要 T 秒并且你有 N 个按钮(在你的例子中是 81),同样在每次迭代中你使用 K乘以该函数(在您的情况下为 3),则总时间为 T * N * K。
解决方案是只调用 finalize_board 一次。
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
all_buttons = list()
layout = qtw.QGridLayout(self)
board = finalize_board()
for x, rows in enumerate(board):
for y, cell in enumerate(rows):
button = qtw.QPushButton(str(cell))
layout.addWidget(button, x, y)
all_buttons.append(button)
self.show()
所以我的程序是一个数独,至此,我已经完成了生成棋盘的代码。我正在尝试将其实现到 pyqt5 中。我通过使按钮对应于数独板中的每个数字(因此有 81 个按钮)来完成此操作。我有一台能够以高帧率玩 运行 三 A 游戏的电脑(如果这很重要的话)。可能是什么问题?我把我的代码放在下面。
import random
import numpy as np
import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
# 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]
# Basically goes through each number and 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
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# -------------------------------------------------------------------------------------------
all_buttons = list()
layout = qtw.QGridLayout()
for x in range(9):
for y in range(9):
if finalize_board()[x][y] == 0: finalize_board()[x][y] = ' '
all_buttons.append(layout.addWidget(qtw.QPushButton(str(finalize_board()[x][y])), x, y))
self.setLayout(layout)
# -------------------------------------------------------------------------------------------
self.show()
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
问题是你正在为每个按钮执行 finalize_board 函数,所以如果函数需要 T 秒并且你有 N 个按钮(在你的例子中是 81),同样在每次迭代中你使用 K乘以该函数(在您的情况下为 3),则总时间为 T * N * K。
解决方案是只调用 finalize_board 一次。
class MainWindow(qtw.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
all_buttons = list()
layout = qtw.QGridLayout(self)
board = finalize_board()
for x, rows in enumerate(board):
for y, cell in enumerate(rows):
button = qtw.QPushButton(str(cell))
layout.addWidget(button, x, y)
all_buttons.append(button)
self.show()