Я собираю для своих учеников простую математическую головоломку под названием Diffy.
Я могу заставить ее работать, но способ обновления qlabel (pixmap) очень хакерский.
Я в основном пересматриваю -инициализировал все qobject-ы при нажатии qpushbutton. Вы можете увидеть это в функции button_click.
Я пытался вызвать update () для qlabel, layout, qwidget, но ни один из них не работал.
Пожалуйста, дайте мне знать, есть ли более элегантный способ .
import sys
from collections import namedtuple
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt, QPoint
class Canvas(QtWidgets.QLabel):
def __init__(self, start_four):
super().__init__()
self.start_four = start_four
self.painter = None
self.pen = None
pixmap = QtGui.QPixmap(800, 800)
pixmap.fill(Qt.white)
self.setPixmap(pixmap)
self.setScaledContents(True)
self.drawing()
def drawing(self):
self.painter = QtGui.QPainter(self.pixmap())
self.pen = QtGui.QPen()
self.pen.setWidth(5)
Point = namedtuple("Point", "x y")
start_point = Point(100, 100)
p0, p1, p2, p3 = self.first_four_corners(start_point, width=600)
num_locations = []
colors = ["red", "orange", "green", "blue", "purple"]
# start_four = [-9, 18, -5, 7]
fours = self.find_fours(self.start_four)
for count in range(5):
color = colors[count]
self.draw_square(p0, p1, p2, p3, color, fours[count])
num_locations.append([p0, p1, p2, p3])
p0, p1, p2, p3 = self.next_four_corners(p0, p1, p2, p3)
self.painter.end()
self.update()
def draw_square(self, p0, p1, p2, p3, color, four_nums):
# print(four_nums)
self.pen.setColor(QtGui.QColor(color))
self.painter.setPen(self.pen)
self.painter.drawLines([
QtCore.QLine(QPoint(*p0), QPoint(*p1)),
QtCore.QLine(QPoint(*p1), QPoint(*p2)),
QtCore.QLine(QPoint(*p2), QPoint(*p3)),
QtCore.QLine(QPoint(*p3), QPoint(*p0)),
])
brush = QtGui.QBrush()
num_color_bg = QtGui.QColor(color)
num_color_bg.setAlpha(120)
brush.setStyle(Qt.SolidPattern)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setBold(True)
num_font_size = 10
font.setPointSize(num_font_size)
self.painter.setFont(font)
for i, p in enumerate([p0, p1, p2, p3]):
# draw circles
brush.setColor(QtGui.QColor("white"))
self.painter.setBrush(brush)
self.painter.drawEllipse(QtCore.QPoint(p.x, p.y), 40, 40)
brush.setColor(num_color_bg)
self.painter.setBrush(brush)
self.painter.drawEllipse(QtCore.QPoint(p.x, p.y), 40, 40)
self.pen.setColor(QtGui.QColor("black"))
self.painter.setPen(self.pen)
num_str = str(four_nums[i])
xoffset = num_font_size * len(num_str) - num_font_size//2
yoffset = num_font_size
self.painter.drawText(p.x-xoffset, p.y + yoffset, num_str)
def first_four_corners(self, top_left_point, width):
Point = namedtuple("Point", "x y", defaults=[0, 0])
p0 = top_left_point
p1 = Point(p0.x + width, p0.y)
p2 = Point(p1.x, p1.y + width)
p3 = Point(p0.x, p0.y+width)
return p0, p1, p2, p3
def next_four_corners(self, p0, p1, p2, p3):
Point = namedtuple("Point", "x y", defaults=[0, 0])
n0 = Point((p0.x+p1.x)//2, (p0.y+p1.y)//2)
n1 = Point((p1.x+p2.x)//2, (p1.y+p2.y)//2)
n2 = Point((p2.x+p3.x)//2, (p2.y+p3.y)//2)
n3 = Point((p3.x+p0.x)//2, (p3.y+p0.y)//2)
return n0, n1, n2, n3
def find_fours(self, start_four):
f0, f1, f2, f3 = start_four
fours = []
fours.append(start_four)
for _ in range(4):
fours.append([abs(f0-f1), abs(f1-f2), abs(f2-f3), abs(f3-f0)])
f0, f1, f2, f3 = abs(f0 - f1), abs(f1 - f2), abs(f2 - f3), abs(f3 - f0)
return fours
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, start_four):
super().__init__()
self.widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
self.widget.setLayout(layout)
self.start_four = start_four
canvas = Canvas(start_four)
layout.addWidget(canvas)
self.input_btn = QtWidgets.QPushButton("Update")
self.input_btn.clicked.connect(self.button_click)
self.input_label = QtWidgets.QLabel("Enter four numbers:")
self.input_num0 = QtWidgets.QLineEdit()
self.input_num1 = QtWidgets.QLineEdit()
self.input_num2 = QtWidgets.QLineEdit()
self.input_num3 = QtWidgets.QLineEdit()
self.input_num0.setText("10")
self.input_num1.setText("10")
self.input_num2.setText("10")
self.input_num3.setText("10")
input_layout = self.get_input_layout()
layout.addLayout(input_layout)
self.setCentralWidget(self.widget)
def get_input_layout(self):
input_layout = QtWidgets.QHBoxLayout()
input_layout.addWidget(self.input_label)
input_layout.addWidget(self.input_num0)
input_layout.addWidget(self.input_num1)
input_layout.addWidget(self.input_num2)
input_layout.addWidget(self.input_num3)
input_layout.addWidget(self.input_btn)
return input_layout
def button_click(self):
num0 = int(self.input_num0.text())
num1 = int(self.input_num1.text())
num2 = int(self.input_num2.text())
num3 = int(self.input_num3.text())
self.start_four = [num0, num1, num2, num3]
self.widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
self.widget.setLayout(layout)
canvas = Canvas(self.start_four)
layout.addWidget(canvas)
input_layout = self.get_input_layout()
layout.addLayout(input_layout)
self.setCentralWidget(self.widget)
# print(self.start_four)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow(start_four=[12, 5, 18, 27])
window.resize(800, 1000)
window.setWindowTitle("Diffy!")
window.show()
app.exec_()