""" @Author: packy945 @FileName: UI.py @DateTime: 2023/4/27 17:42 @SoftWare: PyCharm """ # -*- encoding: utf-8 -*- import tkinter as tk from pprint import pprint from tkinter import * from data import * import time import numpy as np from tkinter import scrolledtext BLACK = "#000000" HINT = '#6D2DFA' SILVER = '#FFFFFF' u_NUMBER = '#6D2DFA' WHITE = "#FFFFFF" ORANGE = '#FF8C00' RED = "#C80000" YELLOW = "#FAE067" GREY = '#808080' GREYLESS = '#CCCCCC' side = 40 # 构建主窗口 width, height = 840, 610#设置长宽 root = tk.Tk()#设置主窗口 root.title("数独")#设置窗口标题 root.config(bg=BLACK)#设置背景 root.geometry(f'{width}x{height}')#设置窗口大小 root.resizable(0, 0) # 防止用户调整尺寸 canvas = tk.Canvas(root, bg=WHITE, bd=2, width=width, height=height, background=ORANGE, highlightthickness=0)#设置画布 canvas.place(x=0, y=0, anchor=NW)#设置画布位置 side = 40 """文字框""" top_x = (side + 3) * 11 # 文本框顶点x top_y = 50 # 文本框顶点y bc_x = (side + 3) * 7 + 20 # 文本框宽度 bc_y = (side + 3) * 12 # 文本框高度 right = tk.Frame(root, bg=WHITE, relief="sunken", width=bc_x, height=bc_y) right.place(x=top_x, y=top_y, anchor=NW) # 右边栏 class MyTimer: # 计时器 def __init__(self): self.elapsed = 0.0 self.running = False self.last_start_time = None self.timestr = tk.IntVar() # 创建可变数据类型 self.min = tk.IntVar() # 创建可变数据类型 self.sec = tk.IntVar() # 创建可变数据类型 self.timestr.set(0) # 只能数值不能等于号 self.starttime = 0 # 开始计时时间 self.elapsedtime = 0.0 # 计时器统计到的时间 self.timer = None self.starttime = time.time() - self.elapsedtime self.update() self.win = 0 def update(self): self.elapsedtime = int(time.time() - self.starttime) self.timestr.set(self.elapsedtime) self.min.set(self.elapsedtime // 60) self.sec.set(self.elapsedtime - self.min.get() * 60) self.timer = root.after(100, self.update) def restart(self): self.win = 0 self.elapsedtime = 0.0 self.starttime = time.time() - self.elapsedtime self.update() def stop(self): if self.win: pass else: self.win = 1 root.after_cancel(self.timer) self.elapsedtime = int(time.time() - self.starttime) now = int(time.time() - self.starttime) self.timestr.set(now) self.min.set(now // 60) self.sec.set(now - self.min.get() * 60) def rect_draw(side, row, col): ''' 绘制一个方格 :param side: 方格边长 :param row: 行 :param col: 列 :return: ''' block_color = [3, 4, 5] # 显色宫格依据 logi_row = row in block_color and col in block_color # 显色逻辑 logi_col = row in block_color or col in block_color # 显色逻辑 if not logi_row and logi_col: color = "#FAE067" else: color = 'white' canvas.create_rectangle(row * (side + 3) + 50, col * (side + 3) + 50, row * (side + 3) + 50 + side, col * (side + 3) + 50 + side, fill=color, width=0) # 绘制一个方格 def draw_all_rect(): """ 左上角开始 :param left_x: :param top_y: :return: """ for i in range(9): for n in range(9): rect_draw(side, i, n) martix_position_mapping = dict() def creat_martix_mapping(side): mapping_dict = dict() offeset_x = 50 side = side + 3 for i in range(9): # 坐标映射 for n in range(9): x = side *i+offeset_x y = side *n+offeset_x mapping_dict[n, i] = [x, y] return mapping_dict def show_Time(timer: MyTimer): ''' 显示计时器 :param timer:计时器示例 :return: ''' Time = tk.Label(right, text="运行时间: 分 秒", bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold'), anchor=W) Time.place(x=30, y=30, width=300, height=30) Min = tk.Label(right, textvariable=timer.min, bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold')) # 分钟计数 Min.place(x=150, y=30, width=30, height=30) Sec = tk.Label(right, textvariable=timer.sec, bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold')) # 秒钟计数 Sec.place(x=220, y=30, width=30, height=30) def num_draw(side, row, col, martix, u_martix): ''' 绘制方格中的数字 :param side: 方格大小 :param row: 行 :param col: 列 :param martix: 原矩阵 :param u_martix: 用户矩阵 :return: ''' if u_martix[row, col] == 10:# 如果该方格为提示信息,则不显示大数字 return if not martix[row, col] == 0: # 如果该方格为题目所给数字(不可更改),则显示为黑色 color = 'black' # 将颜色设置为黑色 else: if u_martix[row, col] not in GetPossible(u_martix, row, col): # 判断这一格的数字是否符合数独要求 color = 'red' # 不符合要求显示红色 else: color = 'purple' # 用户填的数字的颜色 if martix[row, col] != 0 or u_martix[row, col] != 0: #如果该格子有数据要显示 canvas.create_text(col * (side + 3) + 50 + side / 2, row * (side + 3) + 50 + side / 2, text=f"{u_martix[row, col]}", font=('幼圆', 18, 'bold'), fill=color, tags="num") def Difficulty(empty): """ 难度显示: :param empty: 原始空格数目 :return: """ Level = tk.Label(right, text="难度:{:.2f}".format(empty / 81), bg=WHITE, fg=BLACK, font=('幼圆', 16, 'bold'), anchor=W) Level.place(x=30, y=60, width=300, height=30) def noter(tag): ''' 显示笔记提示 :param tag: 笔记模式是否开启 :return: ''' note_help1 = tk.Label(right, text=f"False 时保存笔记,当前笔记:{tag}", bg=WHITE, fg=RED, font=('幼圆', 12, 'bold'), anchor=W) note_help1.place(x=30, y=90, width=300, height=30) def seq_recode(right, STEP): ''' 显示步骤 :param STEP: 步骤 :return: ''' note_help1 = tk.Label(right, text=f"步骤记录:", bg=WHITE, fg=RED, font=('幼圆', 12, 'bold'), anchor=W) note_help1.place(x=30, y=120, width=300, height=30) scr = scrolledtext.ScrolledText(right, fg='red', font=('幼圆', 16, 'bold'))#设置一个可滚动文本框 scr.place(x=30, y=150, width=280, height=300)# for i in range(len(STEP)): if i != 0:#将步骤显示到文本框中 scr.insert('end', f"{STEP[i][:3]}\n") # 末尾插入 scr.config(state=DISABLED) # 设置文本框为 “不能编辑” scr.see(END)#将视图移到末尾 def empty(u_martix): count = 0 # 计数 for i in range(9): for j in range(9): if u_martix[i][j] == 0 or u_martix[i][j] == 10: count += 1 return count if __name__ == "__main__": martix = M = np.array([[1, 3, 4, 0, 0, 6, 0, 0, 7], [0, 9, 2, 0, 0, 7, 0, 5, 6], [0, 6, 7, 8, 9, 4, 0, 2, 3], [0, 8, 1, 2, 4, 9, 6, 0, 0], [9, 4, 5, 6, 0, 8, 2, 3, 0], [2, 7, 6, 0, 1, 5, 9, 0, 4], [0, 2, 8, 0, 5, 1, 0, 0, 9], [0, 1, 3, 0, 6, 0, 0, 4, 8], [0, 5, 0, 4, 0, 0, 0, 1, 2]]) u_M = np.array([[1, 3, 4, 0, 0, 6, 0, 0, 7], [0, 9, 2, 0, 0, 7, 0, 5, 6], [0, 6, 7, 8, 9, 4, 0, 2, 3], [0, 8, 1, 2, 4, 9, 6, 0, 0], [9, 4, 5, 6, 0, 8, 2, 3, 0], [2, 7, 6, 1, 1, 5, 9, 0, 4], [0, 2, 8, 0, 5, 1, 0, 6, 9], [0, 1, 3, 0, 6, 0, 7, 4, 8], [0, 5, 0, 4, 0, 0, 0, 1, 2]]) # text_enter(side) # time1.start() # 计时开始 # draw((5, 5),M,u_martix) side = 40 def left1(event): print(event.x, event.y) x = event.x y = event.y for key, posit_lt in martix_position_mapping.items(): if posit_lt[0] < x < posit_lt[0]+side and posit_lt[1] < y < posit_lt[1]+side: print(key) canvas.bind('', left1) draw_all_rect() martix_position_mapping = creat_martix_mapping(side) seq_recode(right,[]) time1 = MyTimer() # 实例计时器 show_Time(time1) emp = empty(u_M) Difficulty(emp) noter(True) mainloop()