diff --git a/TreeNode.py b/TreeNode.py index a20f53e..fdadab7 100644 --- a/TreeNode.py +++ b/TreeNode.py @@ -12,14 +12,9 @@ from data import * import tkinter.messagebox -sz = [] -A = Aexp([0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]) -img_open = [] -img_png = [] - class Tree: def __init__(self): - self.bc = 40 + self.bc = 70 self.Node = [] self.rootID = None self.deepth = [] @@ -57,7 +52,7 @@ class Tree: self.deep() def calculate(self, node): - print(node) + # print(node) if node[1] == 'Value': return node[5] * 1.0 elif node[1] == 'Operator': @@ -204,154 +199,3 @@ def print_ast(node:TreeNode, prefix='', is_left=True): - - - -if __name__ == '__main__': - expr = "(34-13.121)*2*6" - # ast = build_ast(expr) - # print_ast(ast) - # print(tree.Node) - class Frame_Tree: - # def Frame_tree(): - def __init__(self, window): - self.Tree_root = tk.Frame(window, relief="groove", width=610, height=400) - self.Tree_root.place(x=50, y=250) # 树的显示 - - self.Tree_cv = tk.Canvas(self.Tree_root, width=610, height=400, bg='#b7bcc0') - self.Tree_cv.place(x=0, y=0) - # Tree_cv.create_rectangle(10, 10, 600, 290, width=10, outline='#ff9933') - - bot = tk.Button(self.Tree_root, text='添加运算节点', bg='#cca583', fg='black', ) - bot.place(x=500, y=40, width=80, height=30) - bot = tk.Button(self.Tree_root, text='添加数值节点', bg='#cca583', fg='black', ) - bot.place(x=500, y=75, width=80, height=30) - bot = tk.Button(self.Tree_root, text='改变运算输入', bg='#cca583', fg='black', ) - bot.place(x=500, y=110, width=80, height=30) - bot = tk.Button(self.Tree_root, text='改变节点运算', bg='#cca583', fg='black', ) - bot.place(x=500, y=145, width=80, height=30) - bot = tk.Button(self.Tree_root, text='数值节点交换', bg='#cca583', fg='black', ) - bot.place(x=500, y=180, width=80, height=30) - bot = tk.Button(self.Tree_root, text='产生表达式', bg='#cca583', fg='black', command=lambda: self.Aexp()) - bot.place(x=500, y=215, width=80, height=30) - # bot = tk.Button(self.Tree_root, text='计算', bg='#cca583', fg='black', command=lambda: tree.calculate(tree.Node[tree.rootID])) - # bot.place(x=500, y=250, width=80, height=30) - - - - - def clear(self): - self.Tree_cv.delete('all') - tree.Node = [] - tree.rootID = None - - def Aexp(self): - entry.delete(0, "end") - print(tree.Aexp(tree.Node[tree.rootID])) - entry.insert("end", tree.Aexp(tree.Node[tree.rootID])) - label2 = tk.Label(window, text=f'= {float(tree.calculate(tree.Node[tree.rootID])):.2f}', - font=('宋体', 15, 'bold'), width=30, height=10, - # 设置填充区距离、边框宽度和其样式(凹陷式) - borderwidth=5, relief="sunken") - label2.place(x=240, y=160, width=60, height=50) - - def show_tree(self, ss): - # 清空画布 - self.Tree_cv.delete('all') - build_ast(ss) - for i in range(len(tree.Node)): - tree.deepth.append(-1) - # print(tree.Node) - # print(tree.deepth) - # 格式化树节点的深度 - tree.deep() - # print(tree.deepth) - - # 初始化节点数与深度 - dept, nums = -1, 0 - for i in range(len(tree.deepth)): - dept = max(dept, tree.deepth[i]) - tree.place.append((None, None)) - if tree.deepth[i] == 0: - nums += 1 - # print(dept, nums) - - tree_length = 500 - tree_height = 400 - dx = tree_length // (nums + 1) - dy = tree_height // (dept + 2) - bc = 40 - # 若为数字节点 - cur = 0 - for i in range(len(tree.deepth)): - if tree.deepth[i] == 0: - cur += 1 - tree.place[i] = (cur * dx, tree_height - dy) - self.Tree_cv.create_rectangle(tree.place[i][0] - bc / 2, tree.place[i][1] - bc / 2, - tree.place[i][0] + bc / 2, - tree.place[i][1] + bc / 2, fill='white', width=0) - self.Tree_cv.create_text(tree.place[i][0], tree.place[i][1], text=str(tree.Node[i][5]), - font=('宋体', 15, 'bold'), anchor='center') - - for d in range(dept): - cur_d = d + 1 - for i in range(len(tree.deepth)): - if tree.deepth[i] == cur_d: - lnode = tree.place[tree.Node[i][3]] - rnode = tree.place[tree.Node[i][4]] - node = ((lnode[0] + rnode[0]) / 2, tree_height - (cur_d + 1) * dy) - self.Tree_cv.create_line(lnode[0], lnode[1] - bc / 2, node[0], node[1] + bc / 2, fill='#1ffbe9', - width=2) - self.Tree_cv.create_line(rnode[0], rnode[1] - bc / 2, node[0], node[1] + bc / 2, fill='#1ffbe9', - width=2) - tree.place[i] = node - self.Tree_cv.create_rectangle(tree.place[i][0] - bc / 2, tree.place[i][1] - bc / 2, - tree.place[i][0] + bc / 2, tree.place[i][1] + bc / 2, - fill='white', width=0) - self.Tree_cv.create_text(tree.place[i][0], tree.place[i][1], text=str(tree.Node[i][2]), - font=('宋体', 15, 'bold'), anchor='center') - window = tk.Tk() - var = tk.StringVar() - var2 = tk.StringVar() - width = 700 - height = 700 # 窗口大小 - screen_width = window.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 - screen_height = window.winfo_screenheight() - x = int((screen_width - width) / 2) - y = int((screen_height - height) / 2) - 40 - size = '{}x{}+{}+{}'.format(width, height, x, y) - window.geometry(size) - - - # 基本组件显示 - cv = tk.Canvas(window, width=380, height=136, bg='#FFFFCC') - cv.place(x=100, y=3) - F = Frame_Tree(window) - but = tk.Button(window, text='出题', bg='#ffffcc', fg='black', command=lambda: show_card()) - but.place(x=500, y=20, width=100, height=50, ) - but2 = tk.Button(window, text='换牌', bg='#ffffcc', fg='black', ) - but2.place(x=500, y=80, width=100, height=50, ) - - entry = tk.Entry(window, show=None, font=('宋体', 15, 'bold')) - entry.place(x=50, y=160, width=180, height=50) - label2 = tk.Label(window, text='= 24', font=('宋体', 15, 'bold'), width=30, height=10, - # 设置填充区距离、边框宽度和其样式(凹陷式) - borderwidth=5, relief="sunken") - but4 = tk.Button(window, text='计算', bg='#ffffcc', fg='black', command=lambda: show_result(entry.get(), sz)) - but4.place(x=315, y=165, width=50, height=40, ) - label2.place(x=240, y=160, width=60, height=50) - - but3 = tk.Button(window, text='自动求解', bg='#ffffcc', fg='black', command=lambda: show_answer()) - but3.place(x=250, y=210, width=120, height=40, ) - but3 = tk.Button(window, text='所有答案', bg='#ffffcc', fg='black', command=lambda: show_all()) - but3.place(x=410, y=210, width=120, height=40, ) - - but5 = tk.Button(window, text='画树', bg='#ffffcc', fg='black', command=lambda: F.show_tree(expr)) - but5.place(x=80, y=210, width=120, height=40, ) - - - - # cv1 = tk.Canvas(window, width=380, height=90, bg='#FFFFCC') - # cv1.place(x=100, y=200) - - window.mainloop() diff --git a/butt_test.py b/butt_test.py new file mode 100644 index 0000000..5056adc --- /dev/null +++ b/butt_test.py @@ -0,0 +1,14 @@ +from PIL import Image, ImageDraw, ImageFont + +# 创建一个图像 +image = Image.new("RGB", (100, 100), "white") +draw = ImageDraw.Draw(image) + +# 加载默认字体 +font = ImageFont.load_default() + +# 要获取文本的大小 +text = "Hello, World!" +text_size = draw.textsize(text, font) + +print("Text size:", text_size) diff --git a/data.py b/data.py index 25c5a0b..952684c 100644 --- a/data.py +++ b/data.py @@ -18,7 +18,6 @@ class Aexp: self.Aexp_cur = 0 self.num = 0 self.card = [a, b, c, d] - # print(self.card) self.answer = [] self.Color = [] self.Aexp(a, b, c, d) @@ -94,3 +93,9 @@ def del_parentheses(e): +if __name__ == '__main__': + ans = Aexp(1, 2, 4, 6) + for i in ans.answer: + print(i) + # print(ans) + pass diff --git a/expressions.txt b/expressions.txt new file mode 100644 index 0000000..dce7c22 --- /dev/null +++ b/expressions.txt @@ -0,0 +1,20 @@ +(8 + 3) * (6 - 2) +9 - (4 + 2) * (7 - 1) +(2 * 3) + (5 - 1) / 4 +((7 + 2) - 1) * (8 / 4) +9 * (3 - 1) + (8 / 4) +((9 - 1) / (4 + 1)) + 7 * 3 +(8 - 3) * ((6 + 2) / 4) + 9 +((7 * 2) - 4) * ((9 + 3) / 5) + 1 +(9 + 4) * ((7 - 2) / (8 + 1)) - 6 +((5 - 3) * (9 + 7)) / (8 - 2) + 6 +(6 + 2) * (9 - 3) +8 - (5 + 1) * (7 - 2) +(3 * 4) + (8 - 2) / 5 +((6 + 3) - 2) * (7 / 4) +8 * (2 - 1) + (9 / 3) +((4 - 2) / (9 + 1)) + 5 * 7 +(7 - 2) * ((5 + 3) / 6) + 4 +((6 * 3) - 1) * ((8 + 2) / 5) + 9 +(19 + 21) * ((14 - 11) / (7 + 3)) - 5 +((81 - 45) * (36 + 21)) / (18 - 6) + 7 diff --git a/images/+.png b/images/+.png new file mode 100644 index 0000000..7f19041 Binary files /dev/null and b/images/+.png differ diff --git a/images/-.png b/images/-.png new file mode 100644 index 0000000..ec7d285 Binary files /dev/null and b/images/-.png differ diff --git a/images/0.png b/images/0.png new file mode 100644 index 0000000..1271fe5 Binary files /dev/null and b/images/0.png differ diff --git a/images/1.png b/images/1.png new file mode 100644 index 0000000..23e288d Binary files /dev/null and b/images/1.png differ diff --git a/images/10.png b/images/10.png new file mode 100644 index 0000000..e6b6c7e Binary files /dev/null and b/images/10.png differ diff --git a/images/100.png b/images/100.png new file mode 100644 index 0000000..7dc6cd3 Binary files /dev/null and b/images/100.png differ diff --git a/images/1000.png b/images/1000.png new file mode 100644 index 0000000..17ec470 Binary files /dev/null and b/images/1000.png differ diff --git a/images/11.png b/images/11.png new file mode 100644 index 0000000..5fbcbc2 Binary files /dev/null and b/images/11.png differ diff --git a/images/110.png b/images/110.png new file mode 100644 index 0000000..064505f Binary files /dev/null and b/images/110.png differ diff --git a/images/12.png b/images/12.png new file mode 100644 index 0000000..736b25d Binary files /dev/null and b/images/12.png differ diff --git a/images/123.png b/images/123.png new file mode 100644 index 0000000..39ae0c7 Binary files /dev/null and b/images/123.png differ diff --git a/images/123123.png b/images/123123.png new file mode 100644 index 0000000..71923e4 Binary files /dev/null and b/images/123123.png differ diff --git a/images/1234.png b/images/1234.png new file mode 100644 index 0000000..ecd1def Binary files /dev/null and b/images/1234.png differ diff --git a/images/13.png b/images/13.png new file mode 100644 index 0000000..ee532c8 Binary files /dev/null and b/images/13.png differ diff --git a/images/14.png b/images/14.png new file mode 100644 index 0000000..9bb2a73 Binary files /dev/null and b/images/14.png differ diff --git a/images/18.png b/images/18.png new file mode 100644 index 0000000..e68edbc Binary files /dev/null and b/images/18.png differ diff --git a/images/19.png b/images/19.png new file mode 100644 index 0000000..0e9bf1b Binary files /dev/null and b/images/19.png differ diff --git a/images/2.png b/images/2.png new file mode 100644 index 0000000..8596b21 Binary files /dev/null and b/images/2.png differ diff --git a/images/21.png b/images/21.png new file mode 100644 index 0000000..e74d1d4 Binary files /dev/null and b/images/21.png differ diff --git a/images/3.png b/images/3.png new file mode 100644 index 0000000..4ba48eb Binary files /dev/null and b/images/3.png differ diff --git a/images/36.png b/images/36.png new file mode 100644 index 0000000..46a6d31 Binary files /dev/null and b/images/36.png differ diff --git a/images/4.png b/images/4.png new file mode 100644 index 0000000..0636a61 Binary files /dev/null and b/images/4.png differ diff --git a/images/40.png b/images/40.png new file mode 100644 index 0000000..ace73e4 Binary files /dev/null and b/images/40.png differ diff --git a/images/400.png b/images/400.png new file mode 100644 index 0000000..b3e1f51 Binary files /dev/null and b/images/400.png differ diff --git a/images/4000.png b/images/4000.png new file mode 100644 index 0000000..cc0354c Binary files /dev/null and b/images/4000.png differ diff --git a/images/45.png b/images/45.png new file mode 100644 index 0000000..1056080 Binary files /dev/null and b/images/45.png differ diff --git a/images/5.png b/images/5.png new file mode 100644 index 0000000..d97fd35 Binary files /dev/null and b/images/5.png differ diff --git a/images/520.png b/images/520.png new file mode 100644 index 0000000..dcb780e Binary files /dev/null and b/images/520.png differ diff --git a/images/6.png b/images/6.png new file mode 100644 index 0000000..a96f18c Binary files /dev/null and b/images/6.png differ diff --git a/images/7.png b/images/7.png new file mode 100644 index 0000000..25d0ebc Binary files /dev/null and b/images/7.png differ diff --git a/images/8.png b/images/8.png new file mode 100644 index 0000000..c626da0 Binary files /dev/null and b/images/8.png differ diff --git a/images/81.png b/images/81.png new file mode 100644 index 0000000..0bb2840 Binary files /dev/null and b/images/81.png differ diff --git a/images/9.png b/images/9.png new file mode 100644 index 0000000..ab435ad Binary files /dev/null and b/images/9.png differ diff --git a/images/90.png b/images/90.png new file mode 100644 index 0000000..22402e0 Binary files /dev/null and b/images/90.png differ diff --git a/images/99.png b/images/99.png new file mode 100644 index 0000000..db1eb40 Binary files /dev/null and b/images/99.png differ diff --git a/images/X.png b/images/X.png new file mode 100644 index 0000000..e834e31 Binary files /dev/null and b/images/X.png differ diff --git a/images/background.png b/images/background.png new file mode 100644 index 0000000..deb5206 Binary files /dev/null and b/images/background.png differ diff --git a/images/background1.png b/images/background1.png new file mode 100644 index 0000000..36b481c Binary files /dev/null and b/images/background1.png differ diff --git a/images/background_bottom.png b/images/background_bottom.png new file mode 100644 index 0000000..48027b6 Binary files /dev/null and b/images/background_bottom.png differ diff --git a/images/chushi.png b/images/chushi.png new file mode 100644 index 0000000..d50f5e7 Binary files /dev/null and b/images/chushi.png differ diff --git a/images/chuti.png b/images/chuti.png new file mode 100644 index 0000000..48e0f89 Binary files /dev/null and b/images/chuti.png differ diff --git a/images/false.png b/images/false.png new file mode 100644 index 0000000..199ac1b Binary files /dev/null and b/images/false.png differ diff --git a/images/false_high.png b/images/false_high.png new file mode 100644 index 0000000..e8d27e3 Binary files /dev/null and b/images/false_high.png differ diff --git a/images/img.png b/images/img.png new file mode 100644 index 0000000..59132ba Binary files /dev/null and b/images/img.png differ diff --git a/images/number_ground.png b/images/number_ground.png new file mode 100644 index 0000000..560684d Binary files /dev/null and b/images/number_ground.png differ diff --git a/images/result.png b/images/result.png new file mode 100644 index 0000000..7dad785 Binary files /dev/null and b/images/result.png differ diff --git a/images/true.png b/images/true.png new file mode 100644 index 0000000..efaa9e0 Binary files /dev/null and b/images/true.png differ diff --git a/images/true_high.png b/images/true_high.png new file mode 100644 index 0000000..ca3e71b Binary files /dev/null and b/images/true_high.png differ diff --git a/images/÷.png b/images/÷.png new file mode 100644 index 0000000..65860ea Binary files /dev/null and b/images/÷.png differ diff --git a/images/一致性检查.png b/images/一致性检查.png new file mode 100644 index 0000000..4777349 Binary files /dev/null and b/images/一致性检查.png differ diff --git a/images/产生表达式.png b/images/产生表达式.png new file mode 100644 index 0000000..e1d9359 Binary files /dev/null and b/images/产生表达式.png differ diff --git a/images/前置背景.png b/images/前置背景.png new file mode 100644 index 0000000..f6a2e3c Binary files /dev/null and b/images/前置背景.png differ diff --git a/images/对-高亮.png b/images/对-高亮.png new file mode 100644 index 0000000..b58f89b Binary files /dev/null and b/images/对-高亮.png differ diff --git a/images/对.png b/images/对.png new file mode 100644 index 0000000..d25e813 Binary files /dev/null and b/images/对.png differ diff --git a/images/所有答案.png b/images/所有答案.png new file mode 100644 index 0000000..4718ae3 Binary files /dev/null and b/images/所有答案.png differ diff --git a/images/换牌.png b/images/换牌.png new file mode 100644 index 0000000..10d9a94 Binary files /dev/null and b/images/换牌.png differ diff --git a/images/改变节点运算.png b/images/改变节点运算.png new file mode 100644 index 0000000..7e09fe3 Binary files /dev/null and b/images/改变节点运算.png differ diff --git a/images/改变运算输入.png b/images/改变运算输入.png new file mode 100644 index 0000000..e548d88 Binary files /dev/null and b/images/改变运算输入.png differ diff --git a/images/数值节点交换.png b/images/数值节点交换.png new file mode 100644 index 0000000..8c3a4b7 Binary files /dev/null and b/images/数值节点交换.png differ diff --git a/images/添加数值节点.png b/images/添加数值节点.png new file mode 100644 index 0000000..aa2d685 Binary files /dev/null and b/images/添加数值节点.png differ diff --git a/images/添加运算节点.png b/images/添加运算节点.png new file mode 100644 index 0000000..174a752 Binary files /dev/null and b/images/添加运算节点.png differ diff --git a/images/清空画布.png b/images/清空画布.png new file mode 100644 index 0000000..718fe9d Binary files /dev/null and b/images/清空画布.png differ diff --git a/images/生成表达式.png b/images/生成表达式.png new file mode 100644 index 0000000..10744d9 Binary files /dev/null and b/images/生成表达式.png differ diff --git a/images/生成语法树.png b/images/生成语法树.png new file mode 100644 index 0000000..aabd3e3 Binary files /dev/null and b/images/生成语法树.png differ diff --git a/images/画树.png b/images/画树.png new file mode 100644 index 0000000..7fec5b0 Binary files /dev/null and b/images/画树.png differ diff --git a/images/自动求解.png b/images/自动求解.png new file mode 100644 index 0000000..2763e76 Binary files /dev/null and b/images/自动求解.png differ diff --git a/images/计算.png b/images/计算.png new file mode 100644 index 0000000..cac7003 Binary files /dev/null and b/images/计算.png differ diff --git a/images/错-高亮.png b/images/错-高亮.png new file mode 100644 index 0000000..0e5c0da Binary files /dev/null and b/images/错-高亮.png differ diff --git a/images/错.png b/images/错.png new file mode 100644 index 0000000..80b159f Binary files /dev/null and b/images/错.png differ diff --git a/main.py b/main.py index 67ab916..1a3b3aa 100644 --- a/main.py +++ b/main.py @@ -5,20 +5,39 @@ @DateTime: 2023/5/11 11:34 @SoftWare: PyCharm """ +from tkinter import simpledialog + from data import * +import tkinter as tk import tkinter.messagebox from collections import Counter -from PIL import Image, ImageTk +import random +from itertools import permutations from TreeNode import * -import ttkbootstrap as ttk -from ttkbootstrap.constants import * -from ttkbootstrap import * +from setting import * +from tkinter import * +from PIL import ImageTk +from PIL import Image as imim +import sys + sz = [] A = Aexp([0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]) img_open = [] img_png = [] + +def set_canvas_button(button_pot: list, button_photo: ImageTk.PhotoImage, command, tags=None, bg="#3E97C1"): + button = C.create_image(button_pot[0], button_pot[1], anchor=tk.NW, image=button_photo) + C.tag_bind(button, "", command) + + +def to_image(path, resize=None) -> ImageTk.PhotoImage: + if resize: + return ImageTk.PhotoImage(imim.open(path).resize(resize)) + return ImageTk.PhotoImage(imim.open(path)) + + def change_card(): card = [] for n in tree.Node: @@ -33,6 +52,7 @@ def change_card(): else: tk.messagebox.showinfo('', '无法显示卡牌') + def TorF(flag): ''' 显示答案是否正确 @@ -40,31 +60,51 @@ def TorF(flag): :return: ''' if flag == 1: - clo1 = MARK - clo2 = NOMARK + clo1 = to_image(sys.path[0] + "/./images/对-高亮.png", (30, 30)) + clo2 = to_image(sys.path[0] + "/./images/错.png", (30, 30)) + clo3 = to_image(sys.path[0] + '/./images/chushi.png', (30, 30)) elif flag == 0: - clo1 = NOMARK - clo2 = NOMARK + clo1 = to_image(sys.path[0] + "/./images/对.png", (30, 30)) + clo2 = to_image(sys.path[0] + "/./images/错.png", (30, 30)) + clo3 = to_image(sys.path[0] + '/./images/chushi.png', (30, 30)) else: - clo1 = NOMARK - clo2 = MARK + clo1 = to_image(sys.path[0] + "/./images/对.png", (30, 30)) + clo2 = to_image(sys.path[0] + "/./images/错-高亮.png", (30, 30)) + clo3 = to_image(sys.path[0] + '/./images/chushi.png', (30, 30)) + + label3 = tk.Label(window, image=clo1, relief="sunken", borderwidth=0) + label4 = tk.Label(window, image=clo2, relief="sunken", borderwidth=0) + label5 = tk.Label(window, image=clo3, relief="sunken", borderwidth=0) + label3.image = clo1 + label4.image = clo2 + label5.image = clo3 + if flag == 1: + label3.place(x=ENTRY_WIDTH + 200, y=CARD_CANVAS_HEIGHT + 18, width=30, height=30) + elif flag == 0: + label5.place(x=ENTRY_WIDTH + 200, y=CARD_CANVAS_HEIGHT + 18, width=30, height=30) + else: + label4.place(x=ENTRY_WIDTH + 200, y=CARD_CANVAS_HEIGHT + 18, width=30, height=30) + # label3.place(x=ENTRY_WIDTH + 200, y=CARD_CANVAS_HEIGHT + 18, width=30, height=15) + # label4.place(x=ENTRY_WIDTH + 200, y=CARD_CANVAS_HEIGHT + 8 + 30, width=30, height=15) - label3 = tk.Label(window, text='√', fg=clo1, font=('宋体', 10, 'bold italic'), borderwidth=5, relief="sunken") - label4 = tk.Label(window, text='×', fg=clo2, font=('宋体', 10, 'bold italic'), borderwidth=5, relief="sunken") - label3.place(x=625, y=240, width=30, height=25) - label4.place(x=625, y=270, width=30, height=25) -def ans_cal(ans = None): +def ans_cal(ans=None): + """ + 绘制结果框 + :param ans: + :return: + """ if not ans: - label2 = tk.Label(window, text='= ?', font=('楷体', 18, 'bold'), width=30, height=10, - # 设置填充区距离、边框宽度和其样式(凹陷式) - borderwidth=5, relief="sunken", anchor='w') + label2 = tk.Label(window, text='= ?', font=('楷体', 18, 'bold'), width=30, height=10, background="#4acb69", + # 设置填充区距离、边框宽度和其样式(凹陷式) + borderwidth=0, relief="raised") else: - label2 = tk.Label(window, text=f'={ans}', font=('楷体', 18, 'bold'), width=30, height=10, - # 设置填充区距离、边框宽度和其样式(凹陷式) - borderwidth=5, relief="sunken", anchor='w') - label2.place(x=425, y=240, width=100, height=50) + label2 = tk.Label(window, text=f'={ans}', font=('楷体', 18, 'bold'), width=30, height=10, background="#4acb69", + # 设置填充区距离、边框宽度和其样式(凹陷式) + borderwidth=0, relief="raised") + label2.place(x=ENTRY_WIDTH + LEFT_PADDING + 25, y=CARD_CANVAS_HEIGHT + 15, width=100, height=ENTRY_HEIGHT) + def init(): ans_cal() @@ -74,7 +114,7 @@ def init(): TorF(0) -#展示卡牌 +# 展示卡牌 def show_card(): ''' 随机展示四张卡片 @@ -91,65 +131,36 @@ def show_card(): sz_list = ['a', 'j', 'q', 'k'] for i in range(4): - kp_list.append([random.choice(col_list), random.choice(size_list)]) # 随机生成花色以及点数 + kp_list.append([random.choice(col_list), random.choice(size_list)]) # 随机生成花色以及点数 sz.append([kp_list[i][0], kp_list[i][1], kp_list[i][1]]) if kp_list[i][-1] == '1': kp_list[i][-1] = random.choice(sz_list) sz[i][2] = kp_list[i][-1] + show(kp_list) global A A.refresh(sz[0], sz[1], sz[2], sz[3]) - cv.update() + C.update() + def show(kp_list): # 根据花色以及点数显示卡牌 - # cv = tk.Canvas(window, width=380, height=136, bg='#FFFFCC') # 分配位置 - # cv.place(x=100, y=3) global img_open, img_png img_open = [] img_png = [] - cv.delete('all') - i = 0 #卡牌位置偏移量 + C.delete('card') + i = 150 # 卡牌位置偏移量 for k in range(4): img_open.append( - Image.open("card/" + kp_list[k][0] + "/" + kp_list[k][0] + kp_list[k][1] + '.png').resize((90, 130))) + imim.open(sys.path[0] + "/./card/" + kp_list[k][0] + "/" + kp_list[k][0] + kp_list[k][1] + '.png').resize( + (int((CARD_CANVAS_HEIGHT - 10) * 0.6) + 10, CARD_CANVAS_HEIGHT - 10))) img_png.append(ImageTk.PhotoImage(img_open[k])) - cv.create_image(50 + i, 70, image=img_png[k]) - i += 95 - ''' - img_open.append(Image.open("card/" + kp_list[0][0] + "/" + kp_list[0][0] + kp_list[0][1] + '.png').resize((90, 130))) - img_png.append(ImageTk.PhotoImage(img_open[0])) - cv.create_image(50 + i, 70, image=img_png[0]) - - # img_open = Image.open("card/" + kp_list[0][0] + "/" + kp_list[0][0] + kp_list[0][1] + '.png').resize((90, 130)) - # img_png = ImageTk.PhotoImage(img_open) - # cv.create_image(50 + i, 70, image=img_png) - - i += 95 - img_open.append( - Image.open("card/" + kp_list[1][0] + "/" + kp_list[1][0] + kp_list[1][1] + '.png').resize((90, 130))) - img_png.append(ImageTk.PhotoImage(img_open[1])) - cv.create_image(50 + i, 70, image=img_png[1]) - - # img_open1 = Image.open("card/" + kp_list[1][0] + "/" + kp_list[1][0] + kp_list[1][1] + '.png').resize((90, 130)) - # img_png1 = ImageTk.PhotoImage(img_open1) - # cv.create_image(50 + i, 70, image=img_png1) - i += 95 - - img_open2 = Image.open("card/" + kp_list[2][0] + "/" + kp_list[2][0] + kp_list[2][1] + '.png').resize((90, 130)) - img_png2 = ImageTk.PhotoImage(img_open2) - cv.create_image(50 + i, 70, image=img_png2) - i += 95 - img_open3 = Image.open("card/" + kp_list[3][0] + "/" + kp_list[3][0] + kp_list[3][1] + '.png').resize((90, 130)) - img_png3 = ImageTk.PhotoImage(img_open3) - cv.create_image(50 + i, 70, image=img_png3) - ''' - # window.mainloop() - cv.update() - + C.create_image(50 + i, 100, image=img_png[k], tags="card") + i += int((CARD_CANVAS_HEIGHT - 10) * 0.6) + 80 + C.update() -#展示结果 +# 展示结果 def show_result(ss, sz): ''' 展示计算结果 @@ -157,45 +168,36 @@ def show_result(ss, sz): :param sz: 题中给的卡牌数字 :return: ''' - if len(sz) != 4: - tk.messagebox.showinfo('', '未出题') - return - char_list = [] #用于存放算式中的数字 - for i in range(len(ss)): - if ss[i]>'0' and ss[i]<='9': - char_list.append(ss[i]) - a = Counter(char_list) #计数函数Counter - b = Counter([sz[0][1], sz[1][1], sz[2][1], sz[3][1]]) - if len(char_list) != 4: - tk.messagebox.showinfo('', '请输入符合所给卡牌点数的可运算表达式') - elif a != b: - tk.messagebox.showinfo('', '你的表达式中的点数与所给卡牌点数不同') + numbers = [int(number) for number in re.findall(r'\d+', ss)] + a = Counter(numbers) + # char_list = [] # 用于存放算式中的数字 + # for i in range(len(ss)): + # if '0' < ss[i] <= '9': + # char_list.append(ss[i]) + # a = Counter(char_list) # 计数函数Counter + if sz: + b = Counter([sz[0][1], sz[1][1], sz[2][1], sz[3][1]]) + try: + ans = eval(ss) + except: + tk.messagebox.showinfo('', '表达式不可运算') else: - try: - ans = eval(ss) - except: - tk.messagebox.showinfo('', '表达式不可运算') + ans_cal(int(ans)) + # 设置颜色 + if ans == 24: + TorF(1) else: - ans_cal(int(ans)) - #设置颜色 - if ans == 24: - TorF(1) - else: - TorF(-1) + TorF(-1) -#展示一个可行算式 +# 展示一个可行算式 def show_answer(): # 自动求解 if len(sz) != 4: tk.messagebox.showinfo('', '未出题') return - try: - answer = (A.answer[0], A.Color[0]) - A.Aexp_cur = 0 - except: - tk.messagebox.showinfo('', '出错') - return + + answer = (A.answer[0], A.Color[0]) # print() # print(answer) if A.num == 0: @@ -204,11 +206,6 @@ def show_answer(): else: entry.delete(0, "end") entry.insert("end", answer[0]) - ''' - Treenode = Decomposition(answer) - label_answer = tk.Label(window,text=answer+' '+str(Treenode),bg="#FFFFCC",fg="black") - label_answer.place(x=105,y=210) - ''' F.show_tree(answer) if A.num > 1: all_ans["state"] = 'normal' @@ -229,15 +226,14 @@ def show_next(): tk.messagebox.showinfo('', '已显示所有答案') - -#显示所有答案,通过一个新窗口 +# 显示所有答案,通过一个新窗口 def show_all(): global Aexp_cur answer = Aexp(int(sz[0][1]), int(sz[1][1]), int(sz[2][1]), int(sz[3][1])) # Tree_all = [] # for item in answer: - # Tree_all.append(Decomposition(item)) + # Tree_all.append(Decomposition(item)) root = tk.Tk() # root.geometry('500x300') width = 500 @@ -251,47 +247,100 @@ def show_all(): b1 = tk.Scrollbar(root, width=40) # b1.place(x=410,y=200) b1.pack(side=tk.RIGHT, fill=tk.Y) - b2 = tk.Listbox(root, yscrollcommand=b1.set,width=100) + b2 = tk.Listbox(root, yscrollcommand=b1.set, width=100) for i in range(len(answer)): - b2.insert(tk.END,answer[i]) + b2.insert(tk.END, answer[i]) b2.pack(side=tk.LEFT, fill=tk.BOTH) # b2.place(x=520,y=100) b1.config(command=b2.yview) root.mainloop() -def BUTs(): - global all_ans - but = tk.Button(window, text='出题', bg='#ffffcc', fg='black', command=lambda: show_card()) - but.place(x=500, y=20, width=100, height=50, ) - but2 = tk.Button(window, text='换牌', bg='#ffffcc', fg='black', command=lambda: change_card()) - but2.place(x=500, y=80, width=100, height=50, ) - - but4 = tk.Button(window, text='计算', bg='#ffffcc', fg='black', command=lambda: show_result(entry.get(), sz)) - but4.place(x=530, y=240, width=80, height=50, ) - - but3 = tk.Button(window, text='自动求解', bg='#ffffcc', fg='black', command=lambda: show_answer()) - but3.place(x=250, y=210, width=120, height=40, ) - all_ans = tk.Button(window, text='所有答案', bg='#ffffcc', fg='black', command=lambda: show_next(), state='disable') - all_ans.place(x=410, y=210, width=120, height=40, ) +def Buts(): + global all_ans + global but5 + but_image = to_image(sys.path[0] + "/./images/chuti.png", (TOP_BUTTON_WIDTH, TOP_BUTTON_HEIGHT)) + but = Button(window, image=but_image, command=show_card, bd=0, relief="solid", bg="#141414", highlightthickness=0) + but.image = but_image + but.place(x=CARD_CANVAS_WIDTH + TOP_BUTTON_WIDTH + 50, y=40, width=TOP_BUTTON_WIDTH, height=TOP_BUTTON_HEIGHT) + + but2_image = to_image(sys.path[0] + "/./images/换牌.png", (TOP_BUTTON_WIDTH, TOP_BUTTON_HEIGHT)) + but2 = tk.Button(window, image=but2_image, command=show_card, bd=0, relief="solid", bg="#141414", + highlightthickness=0) + but2.image = but2_image + but2.place(x=CARD_CANVAS_WIDTH + TOP_BUTTON_WIDTH + 50, y=70 + TOP_BUTTON_HEIGHT, width=TOP_BUTTON_WIDTH, + height=TOP_BUTTON_HEIGHT, ) + + but4_image = to_image(sys.path[0] + "/./images/计算.png", (MIDDLE_BUTTON_WIDTH, MIDDLE_BUTTON_HEIGHT)) + but4 = tk.Button(window, image=but4_image, command=lambda: show_result(entry.get(), sz), bd=0, relief="solid", + bg="#141414", highlightthickness=0) + but4.place(x=ENTRY_WIDTH + 245, y=CARD_CANVAS_HEIGHT + 15, width=MIDDLE_BUTTON_WIDTH, height=MIDDLE_BUTTON_HEIGHT, ) + but4.image = but4_image + + ##报错 + but3_image = to_image(sys.path[0] + "/./images/自动求解.png", (MIDDLE_BUTTON_WIDTH, MIDDLE_BUTTON_HEIGHT)) + but3 = tk.Button(window, image=but3_image, command=lambda: show_answer(), bd=0, relief="solid", bg="#141414", + highlightthickness=0) + but3.place(x=60, y=CARD_CANVAS_HEIGHT + 65, width=MIDDLE_BUTTON_WIDTH, + height=MIDDLE_BUTTON_HEIGHT, ) + but3.image = but3_image + + all_ans_image = to_image(sys.path[0] + "/./images/所有答案.png", (MIDDLE_BUTTON_WIDTH, MIDDLE_BUTTON_HEIGHT)) + all_ans = tk.Button(window, image=all_ans_image, command=lambda: show_next(), bd=0, relief="solid", bg="#141414", + highlightthickness=0, state='disable') + all_ans.place(x=60 + MIDDLE_BUTTON_WIDTH * 2 + 50 * 2, y=CARD_CANVAS_HEIGHT + 65, width=MIDDLE_BUTTON_WIDTH, + height=MIDDLE_BUTTON_HEIGHT, ) + all_ans.image = all_ans_image + + ##报错 + but5_image = to_image(sys.path[0] + "/./images/画树.png", (MIDDLE_BUTTON_WIDTH, MIDDLE_BUTTON_HEIGHT)) + but5 = tk.Button(window, image=but5_image, command=lambda: F.show_tree(entry.get()), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + + but5.place(x=60 + MIDDLE_BUTTON_WIDTH + 50, y=CARD_CANVAS_HEIGHT + 65, width=MIDDLE_BUTTON_WIDTH, + height=MIDDLE_BUTTON_HEIGHT, ) + but5.image = but5_image + + but6_image = to_image(sys.path[0] + '/./images/生成表达式.png', (MIDDLE_BUTTON_WIDTH, MIDDLE_BUTTON_HEIGHT)) + but6 = tk.Button(window, image=but6_image, command=lambda: expressions(), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + but6.place(x=60 + MIDDLE_BUTTON_WIDTH * 3 + 50 * 3, y=CARD_CANVAS_HEIGHT + 65, width=MIDDLE_BUTTON_WIDTH, + height=MIDDLE_BUTTON_HEIGHT, ) + but6.image = but6_image + + ##报错 + but7_image = to_image(sys.path[0] + '/./images/生成语法树.png', (MIDDLE_BUTTON_WIDTH, MIDDLE_BUTTON_HEIGHT)) + but7 = tk.Button(window, image=but7_image, command=lambda: F.show_tree(expression_tree()), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + but7.place(x=60 + MIDDLE_BUTTON_WIDTH * 4 + 50 * 4, y=CARD_CANVAS_HEIGHT + 65, width=MIDDLE_BUTTON_WIDTH, + height=MIDDLE_BUTTON_HEIGHT, ) + but7.image = but7_image + + but8_image = to_image(sys.path[0] + '/./images/一致性检查.png', (MIDDLE_BUTTON_WIDTH, MIDDLE_BUTTON_HEIGHT)) + but8 = tk.Button(window, image=but8_image, command=lambda: examine(), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + but8.place(x=60 + MIDDLE_BUTTON_WIDTH * 5 + 50 * 5, y=CARD_CANVAS_HEIGHT + 65, width=MIDDLE_BUTTON_WIDTH, + height=MIDDLE_BUTTON_HEIGHT, ) + but8.image = but8_image - but5 = tk.Button(window, text='画树', bg='#ffffcc', fg='black', command=lambda: F.show_tree(entry.get())) - but5.place(x=80, y=210, width=120, height=40, ) def left2(event): # 查找鼠标左键按下时位置是否在某个牌上 # print(event.x, event.y) # if not A.card - left = [5, 100, 195, 290] - right = [95, 190, 285, 380] + left = [] + right = [] + i = 150 + for j in range(4): + left.append(i) + right.append(i + (CARD_CANVAS_HEIGHT - 10) * 0.6) + i += int((CARD_CANVAS_HEIGHT - 10) * 0.6) + 80 up = 5 - down = 135 - ''' - for i in range(4): - if up <= event.y <= down and right[i] >= event.x >= left[i]: - print(i + 1) - print(A.card[i]) - ''' + down = CARD_CANVAS_HEIGHT - 10 # 添加数值节点 if F.mode == 2: for cur in range(4): @@ -305,7 +354,6 @@ def left2(event): if node[1] == 'Value': b.append([node[6], node[5]]) c = a.copy() - for x in b: for i in range(len(c)): try: @@ -319,7 +367,9 @@ def left2(event): for l in c: # 若所选card还没有对应的节点,则新建一个数值节点 if not flag and l[0] == A.card[cur][0] and l[1] == int(A.card[cur][1]): - tree.Node.append([len(tree.Node), 'Value', None, None, None, int(A.card[cur][1]), A.card[cur][0]]) + tree.Node.append( + [len(tree.Node), 'Value', None, None, None, int(A.card[cur][1]), A.card[cur][0]]) + print(tree.Node) flag = 1 if not flag: @@ -381,63 +431,96 @@ class Frame_Tree: 5 数值节点交换 ''' self.tips = '' - self.Tree_root = tk.Frame(window, relief="groove", width=610, height=400) - self.Tree_root.place(x=50, y=250) # 树的显示 - - self.Tree_cv = tk.Canvas(self.Tree_root, width=610, height=400, bg='#b7bcc0') - self.Tree_cv.place(x=0, y=0) - # Tree_cv.create_rectangle(10, 10, 600, 290, width=10, outline='#ff9933') - - self.opt1 = tk.Button(self.Tree_root, text='+', bg='#cca583', fg='black', command=lambda: self.set_opt(1)) - self.opt1.place(x=500, y=20, width=30, height=30) - self.opt2 = tk.Button(self.Tree_root, text='-', bg='#cca583', fg='black', command=lambda: self.set_opt(2)) - self.opt2.place(x=535, y=20, width=30, height=30) - self.opt3 = tk.Button(self.Tree_root, text='*', bg='#cca583', fg='black', command=lambda: self.set_opt(3)) - self.opt3.place(x=500, y=55, width=30, height=30) - self.opt4 = tk.Button(self.Tree_root, text='/', bg='#cca583', fg='black', command=lambda: self.set_opt(4)) - self.opt4.place(x=535, y=55, width=30, height=30) + self.Tree_cv = C + add_image = to_image(sys.path[0] + "/./images/+.png", (40, 40)) + self.opt1 = tk.Button(window, image=add_image, command=lambda: self.set_opt(1), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + self.opt1.image = add_image + self.opt1.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 200, width=40, height=40) + + jian_image = to_image(sys.path[0] + "/./images/-.png", (40, 40)) + self.opt2 = tk.Button(window, image=jian_image, command=lambda: self.set_opt(2), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + self.opt2.place(x=TREE_CANVAS_WIDTH - 10, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 200, width=40, height=40) + self.opt2.image = jian_image + + chen_image = to_image(sys.path[0] + "/./images/X.png", (40, 40)) + self.opt3 = tk.Button(window, image=chen_image, command=lambda: self.set_opt(3), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + self.opt3.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 250, width=40, height=40) + self.opt3.image = chen_image + + chu_image = to_image(sys.path[0] + "/./images/÷.png", (40, 40)) + self.opt4 = tk.Button(window, image=chu_image, command=lambda: self.set_opt(4), bd=0, relief="solid", + bg="#141414", + highlightthickness=0) + self.opt4.place(x=TREE_CANVAS_WIDTH - 10, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 250, width=40, height=40) + self.opt4.image = chu_image self.set_opt(1) - dy = 50 - - bot = tk.Button(self.Tree_root, text='添加运算节点', bg='#cca583', fg='black', command=lambda: self.add_opt()) - bot.place(x=500, y=40 + dy, width=80, height=30) - bot = tk.Button(self.Tree_root, text='添加数值节点', bg='#cca583', fg='black', command=lambda: self.add_num()) - bot.place(x=500, y=75 + dy, width=80, height=30) - bot = tk.Button(self.Tree_root, text='改变运算输入', bg='#cca583', fg='black', command=lambda: self.change_num()) - bot.place(x=500, y=110 + dy, width=80, height=30) - bot = tk.Button(self.Tree_root, text='改变节点运算', bg='#cca583', fg='black', command=lambda: self.change_opt()) - bot.place(x=500, y=145 + dy, width=80, height=30) - bot = tk.Button(self.Tree_root, text='数值节点交换', bg='#cca583', fg='black', command=lambda: self.change_node()) - bot.place(x=500, y=180 + dy, width=80, height=30) - bot = tk.Button(self.Tree_root, text='产生表达式', bg='#cca583', fg='black', command=lambda: self.Aexp()) - bot.place(x=500, y=215 + dy, width=80, height=30) - bot = tk.Button(self.Tree_root, text='清空画布', bg='#cca583', fg='black', command=lambda: self.clear()) - bot.place(x=500, y=250 + dy, width=80, height=30) - # bot = tk.Button(self.Tree_root, text='计算', bg='#cca583', fg='black', command=lambda: tree.calculate(tree.Node[tree.rootID])) - # bot.place(x=500, y=250, width=80, height=30) - self.Tree_cv.bind('', self.left1) - self.draw() + dy = 150 + + bot_image = to_image(sys.path[0] + "/./images/添加运算节点.png", (100, 50)) + bot1 = tk.Button(window, image=bot_image, bd=0, relief="solid", bg="#141414", + highlightthickness=0, command=lambda: self.add_opt()) + bot1.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 150 + dy, width=100, height=50) + bot1.image = bot_image + + bot2_image = to_image(sys.path[0] + "/./images/添加数值节点.png", (100, 50)) + bot2 = tk.Button(window, image=bot2_image, bd=0, relief="solid", bg="#141414", + highlightthickness=0, command=lambda: self.add_number()) + bot2.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 200 + dy, width=100, height=50) + bot2.image = bot2_image + + bot3_image = to_image(sys.path[0] + "/./images/改变运算输入.png", (100, 50)) + bot3 = tk.Button(window, image=bot3_image, bd=0, relief="solid", bg="#141414", + highlightthickness=0, command=lambda: self.change_num()) + bot3.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 250 + dy, width=100, height=50) + bot3.image = bot3_image + + bot4_image = to_image(sys.path[0] + "/./images/改变节点运算.png", (100, 50)) + bot4 = tk.Button(window, image=bot4_image, bd=0, relief="solid", bg="#141414", + highlightthickness=0, command=lambda: self.change_opt()) + bot4.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 300 + dy, width=100, height=50) + bot4.image = bot4_image + + bot5_image = to_image(sys.path[0] + "/./images/数值节点交换.png", (100, 50)) + bot5 = tk.Button(window, image=bot5_image, bd=0, relief="solid", bg="#141414", + highlightthickness=0, command=lambda: self.change_node()) + bot5.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 350 + dy, width=100, height=50) + bot5.image = bot5_image + + #bot6_image = to_image(sys.path[0] + "/./images/产生表达式.png", (80, 30)) + #bot6 = tk.Button(window, image=bot6_image, bd=0, relief="solid", bg="#141414", + # highlightthickness=0, command=lambda: self.Aexp()) + #bot6.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 400 + dy, width=80, height=30) + #bot6.image = bot6_image + + bot7_image = to_image(sys.path[0] + "/./images/清空画布.png", (100, 50)) + bot7 = tk.Button(window, image=bot7_image, bd=0, relief="solid", bg="#141414", + highlightthickness=0, command=lambda: self.clear()) + bot7.place(x=TREE_CANVAS_WIDTH - 50, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 400 + dy, width=100, height=50) + bot7.image = bot7_image + self.draw() def set_opt(self, x): - # self.opt1["state"] = "disable" - # exec('self.opt1["state"] = "disable"') opt = ['+', '-', '*', '/'] self.opt = opt[x - 1] for i in range(4): exec('self.opt' + str(i + 1) + '["state"] = "normal"') - exec('self.opt' + str(i + 1) + "['bg']='#cca583'") + exec('self.opt' + str(i + 1) + "['bg']='#131415'") exec('self.opt' + str(i + 1) + "['fg']='black'") exec('self.opt' + str(x) + "['state']='disable'") exec('self.opt' + str(x) + "['bg']='#8f735c'") exec('self.opt' + str(x) + "['fg']='white'") - # 8f735c self.draw() - def add_opt(self): tree.remark() self.tips = '请选择两个节点' @@ -462,6 +545,17 @@ class Frame_Tree: self.mode = 2 self.draw() + def add_number(self): + root = Tk() + root.withdraw() + number = simpledialog.askfloat("输入框", "请输入数字:") + if number is not None: + tree.remark() + self.mode = 2 + tree.Node.append( + [len(tree.Node), 'Value', None, None, None, int(number), 'Spade']) + self.draw() + def change_num(self): tree.remark() self.tips = '请选择一个数值节点' @@ -469,19 +563,6 @@ class Frame_Tree: self.draw() def left1(self, event): - # 查找鼠标左键按下时位置是否在某个节点内,并根据当前操作模式进行反馈 - ''' - print(event.x, event.y) - i = 0 - print(tree.place) - - for T in tree.place: - if abs(event.x - T[0]) <= tree.bc / 2 and abs(event.y - T[1]) <= tree.bc / 2: - # tree.mark[i] = not tree.mark[i] - print(tree.Node[i]) - - i += 1 - ''' # 无操作 if self.mode == 0: return @@ -595,9 +676,8 @@ class Frame_Tree: tree.remark() self.draw() - def clear(self): - self.Tree_cv.delete('all') + self.Tree_cv.delete('tree') tree.Node = [] tree.rootID = None @@ -609,7 +689,6 @@ class Frame_Tree: tk.messagebox.showinfo('', '语法树不合法') return entry.insert("end", exp) - # ans = int(tree.calculate(tree.Node[tree.rootID])) ans = float(tree.calculate(tree.Node[tree.rootID])) ans_cal(f'{float(tree.calculate(tree.Node[tree.rootID])):.2f}') if ans == 24: @@ -622,13 +701,13 @@ class Frame_Tree: if exp[i] > '0' and exp[i] <= '9': char_list.append(exp[i]) a = Counter(char_list) # 计数函数Counter - b = Counter([sz[0][1], sz[1][1], sz[2][1], sz[3][1]]) - if len(char_list) != 4: - tk.messagebox.showinfo('', '请输入符合所给卡牌点数的可运算表达式') + # b = Counter([sz[0][1], sz[1][1], sz[2][1], sz[3][1]]) + # if len(char_list) != 4: + # tk.messagebox.showinfo('', '请输入符合所给卡牌点数的可运算表达式') def show_tree(self, ss): # 清空画布 - self.Tree_cv.delete('all') + self.Tree_cv.delete('tree') if len(ss) == 0: tk.messagebox.showinfo('', '表达式不存在') return @@ -636,16 +715,29 @@ class Frame_Tree: build_ast(ss) self.draw() + def element(self, path): + # 加载图元对应的图片文件 + img = Image.open(path) + # 使用resize方法调整图片 + img = img.resize((70, 70)) + # 把Image对象转换成PhotoImage对象 + img = ImageTk.PhotoImage(img) + # 保存图片的引用,防止被垃圾回收 + window.img = img + return img def draw(self): - self.Tree_cv.delete('all') + self.Tree_cv.delete('tree') mode = ['无', '添加运算节点', '添加数值节点', '改变运算输入', '改变节点运算', '数值节点交换', '添加数值节点'] - lab1 = tk.Label(self.Tree_cv, text='当前操作:', bg='#b7bcc0', font=('宋体', 14, 'bold'), borderwidth=5, anchor='w') - lab1.place(x=30, y=10, width=90, height=30) - lab2 = tk.Label(self.Tree_cv, text=mode[self.mode], bg='#b7bcc0', font=('宋体', 14, 'bold'), borderwidth=5, anchor='w') - lab2.place(x=120, y=10, width=150, height=30) - lab3 = tk.Label(self.Tree_cv, text=self.tips, bg='#b7bcc0', font=('宋体', 14, 'bold'), borderwidth=5, anchor='w') - lab3.place(x=300, y=10, width=200, height=30) + lab1 = tk.Label(self.Tree_cv, text='当前操作:', bg='#131415', fg="white", font=('微软雅黑', 14, 'bold'), + borderwidth=0, anchor='w') + lab1.place(x=30, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 100, width=90, height=30) + lab2 = tk.Label(self.Tree_cv, text=mode[self.mode], bg='#131415', fg="white", font=('微软雅黑', 14, 'bold'), + borderwidth=5, anchor='w') + lab2.place(x=120, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 100, width=150, height=30) + lab3 = tk.Label(self.Tree_cv, text=self.tips, bg='#131415', fg="white", font=('微软雅黑', 14, 'bold'), + borderwidth=5, anchor='w') + lab3.place(x=300, y=CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 100, width=200, height=30) tree.deepth = [] for i in range(len(tree.Node)): @@ -662,24 +754,21 @@ class Frame_Tree: if tree.deepth[i] == 0: nums += 1 - tree_length = 500 - tree_height = 400 + tree_length = TREE_CANVAS_WIDTH + tree_height = TREE_CANVAS_HEIGHT * 0.7 dx = tree_length // (nums + 1) dy = tree_height // (dept + 2) # 若为数字节点 cur = 0 for i in range(len(tree.deepth)): if tree.deepth[i] == 0: + draw_number(str(tree.Node[i][5])) # 生成数字图片 + img = self.element(sys.path[0] + "/./images/{}.png".format(tree.Node[i][5])) # 生成图片对象 img + NUMBER_IMAGES.append(img) # 防止覆盖,将图片保存在图片列表里 cur += 1 - tree.place[i] = (cur * dx, tree_height - dy) - color = 'white' - if tree.mark[i]: - color = '#d1d2c8' - self.Tree_cv.create_rectangle(tree.place[i][0] - tree.bc / 2, tree.place[i][1] - tree.bc / 2, - tree.place[i][0] + tree.bc / 2, - tree.place[i][1] + tree.bc / 2, fill=color, width=0) - self.Tree_cv.create_text(tree.place[i][0], tree.place[i][1], text=str(tree.Node[i][5]), - font=('宋体', 15, 'bold'), anchor='center') + tree.place[i] = (cur * dx, tree_height - dy + CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 200) + self.Tree_cv.create_image(tree.place[i][0] - tree.bc / 2, tree.place[i][1] - tree.bc / 2, + image=img, anchor=NW, tags="tree") for d in range(dept): cur_d = d + 1 @@ -687,95 +776,142 @@ class Frame_Tree: if tree.deepth[i] == cur_d: lnode = tree.place[tree.Node[i][3]] rnode = tree.place[tree.Node[i][4]] - node = ((lnode[0] + rnode[0]) / 2, tree_height - (cur_d + 1) * dy) - self.Tree_cv.create_line(lnode[0], lnode[1] - tree.bc / 2, node[0], node[1] + tree.bc / 2, - fill='#1ffbe9', width=2) - self.Tree_cv.create_line(rnode[0], rnode[1] - tree.bc / 2, node[0], node[1] + tree.bc / 2, - fill='#1ffbe9', width=2) + node = ( + (lnode[0] + rnode[0]) / 2, + tree_height - (cur_d + 1) * dy + CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 150) + self.Tree_cv.create_line(lnode[0], lnode[1] - tree.bc / 2 + 10, node[0], node[1] + tree.bc / 2 - 10, + fill='#246B80', width=1, tags="tree") + self.Tree_cv.create_line(rnode[0], rnode[1] - tree.bc / 2 + 10, node[0], node[1] + tree.bc / 2 - 10, + fill='#246B80', width=1, tags="tree") tree.place[i] = node color = 'white' if tree.mark[i]: color = '#d1d2c8' - self.Tree_cv.create_rectangle(tree.place[i][0] - tree.bc / 2, tree.place[i][1] - tree.bc / 2, - tree.place[i][0] + tree.bc / 2, tree.place[i][1] + tree.bc / 2, - fill=color, width=0) - self.Tree_cv.create_text(tree.place[i][0], tree.place[i][1], text=str(tree.Node[i][2]), - font=('宋体', 15, 'bold'), anchor='center') - + self.Tree_cv.create_image(tree.place[i][0] - tree.bc / 2, tree.place[i][1] - tree.bc / 2, + image=FUNCTION_IMAGES[str(tree.Node[i][2])], anchor=NW, tags="tree") self.Tree_cv.update() -window = Window() -screen_width = window.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 -screen_height = window.winfo_screenheight() + +# 随机生成表达式 +def expressions(): + init() + but5.configure(state='disabled') + with open(sys.path[0]+'/./expressions.txt', 'r') as file: + expressions = file.readlines() + random_expression = random.choice(expressions) + entry.insert("end", random_expression.strip()) + + +# 随机生成语法树 +def expression_tree(): + init() + with open(sys.path[0]+'/./expressions.txt', 'r') as file: + expressions = file.readlines() + random_expression = random.choice(expressions) + return random_expression + + +# 一致性检查 +def examine(): + expression = entry.get() + if expression == '': + return tk.messagebox.showinfo(message='请输入表达式!') + expression_ans = eval(expression) # 计算用户输入的表达式的值 + try: + tree_ans = float(tree.calculate(tree.Node[tree.rootID])) + if expression_ans == tree_ans: + but5.configure(state='active') + tk.messagebox.showinfo('', '语法树与表达式一致!') + else: + tk.messagebox.showinfo('', '语法树与表达式不一致!') + except: + return tk.messagebox.showinfo(message='请绘制语法树!') + + + +from PIL import Image, ImageDraw, ImageFont + + +# 绘制数字图片 +def draw_number(number): + # 打开背景图片 + background_image = Image.open(sys.path[0] + "/./images/number_ground.png") + # 设置图片尺寸 + image_width = 48 + image_height = 48 + # 缩放背景图片 + background_image = background_image.resize((image_width, image_height)) + # 创建空白图片 + image = Image.new("RGBA", (image_width, image_height), (255, 255, 255, 0)) + # 在空白图片上绘制背景图片 + image.paste(background_image, (0, 0)) + # 设置字体和字号 +#以下字体出现问题,已经注释 + # if int(number) < 100: + # font = ImageFont.truetype("arial.ttf", 15) + # elif 100 <= int(number) <= 999: + # font = ImageFont.truetype("arial.ttf", 13) + # else: + # font = ImageFont.truetype("arial.ttf", 9) + + # 创建绘图对象 + draw = ImageDraw.Draw(image) + # 计算文字位置居中 +#以下字体出现问题,已经注释,font=font + bbox = draw.textbbox((0, 0), number) + text_width = bbox[2] - bbox[0] + text_height = bbox[3] - bbox[1] + # text_width, text_height = 15,9 + # text_width, text_height = draw.textsize(number, font=font) + text_x = (image_width - text_width) // 2 - 1 + text_y = (image_height - text_height) // 2 - 1 + # 在图片上绘制数字 +#以下字体出现问题,已经注释,font=font + draw.text((text_x, text_y), number,fill="rgb(88,204,230)") + # 保存图片 + file = sys.path[0] + "/./images/" + number + ".png" + image.save(file) + + +def click(event): + if event.y < CARD_CANVAS_HEIGHT: + left2(event) + else: + F.left1(event) + + +window = tk.Tk() +window.title('二十四点') +NUMBER_IMAGES = [] +FUNCTION_IMAGES = { + "+": ImageTk.PhotoImage(imim.open(sys.path[0] + "/./images/+.png").resize((70, 70))), + "-": ImageTk.PhotoImage(imim.open(sys.path[0] + "/./images/-.png").resize((70, 70))), + "*": ImageTk.PhotoImage(imim.open(sys.path[0] + "/./images/X.png").resize((70, 70))), + "/": ImageTk.PhotoImage(imim.open(sys.path[0] + "/./images/÷.png").resize((70, 70))) +} var = tk.StringVar() var2 = tk.StringVar() -width = int(screen_width*0.8) -height = int(screen_height*0.8 ) # 窗口大小 +width = WINDOW_WIDTH +height = WINDOW_HEIGHT # 窗口大小 +screen_width = window.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 +screen_height = window.winfo_screenheight() x = int((screen_width - width) / 2) -y = int((screen_height - height) / 2) - 40 +y = int((screen_height - height) / 2)#-40 size = '{}x{}+{}+{}'.format(width, height, x, y) window.geometry(size) - +window.resizable(True, True) +window.resizable(False, False) +C = Canvas(window, bg="blue", height=WINDOW_HEIGHT, width=WINDOW_WIDTH) +filename = ImageTk.PhotoImage(imim.open(BACKGROUND_IMG).resize((WINDOW_WIDTH, WINDOW_HEIGHT))) # 创建语法树的背景图片 +C.create_image(0, 0, image=filename, anchor=NW) +qianzhi = ImageTk.PhotoImage(imim.open(sys.path[0] + "/./images/前置背景.png").resize((WINDOW_WIDTH, 30))) +C.create_image(0, CARD_CANVAS_HEIGHT + ENTRY_HEIGHT + 70, image=qianzhi, anchor=NW) +C.pack() F = Frame_Tree(window) -#基本组件显示 -cv = Canvas(window, width=width, height=height * 0.3, background='red') -cv.place(x=0, y=3) -cv.bind('', left2) +C.bind('', click) entry = tk.Entry(window, show=None, font=('宋体', 15, 'bold')) -entry.place(x=25, y=240, width=400, height=50) +entry.place(x=LEFT_PADDING, y=CARD_CANVAS_HEIGHT + 15, width=ENTRY_WIDTH, height=ENTRY_HEIGHT) all_ans = None -BUTs() - - - -''' - -label3 = tk.Label(window,text='√',fg='#cccccc',font=('宋体', 10, 'bold italic'), borderwidth=5, relief="sunken") -label4 = tk.Label(window,text='×',fg='#cccccc',font=('宋体', 10, 'bold italic'), borderwidth=5, relief="sunken") -label3.place(x=360,y=160,width=30,height=25) -label4.place(x=360,y=180,width=30,height=25) -label2 = tk.Label(window, text='= ?', font=('宋体', 15, 'bold'), width=30, height=10, - # 设置填充区距离、边框宽度和其样式(凹陷式) - borderwidth=5, relief="sunken") -label2.place(x=240, y=160, width=60, height=50) -''' +Buts() init() -# cv1 = tk.Canvas(window, width=380, height=90, bg='#FFFFCC') -# cv1.place(x=100, y=200) - - -''' -cv = tk.Canvas(window, width=610, height=300, bg='#ffffff') -cv.place(x=3, y=310) -cv.create_rectangle(10,10,600,290,width=10,outline='#ff9933') - - - -bot = tk.Button(window,text='添加运算节点',bg='#ffffcc',fg='black',) -bot.place(x=500,y=340,width=80,height=30) -bot = tk.Button(window,text='添加数值节点',bg='#ffffcc',fg='black',) -bot.place(x=500,y=375,width=80,height=30) -bot = tk.Button(window,text='改变运算输入',bg='#ffffcc',fg='black',) -bot.place(x=500,y=410,width=80,height=30) -bot = tk.Button(window,text='改变节点运算',bg='#ffffcc',fg='black',) -bot.place(x=500,y=445,width=80,height=30) -bot = tk.Button(window,text='数值节点交换',bg='#ffffcc',fg='black',) -bot.place(x=500,y=480,width=80,height=30) -bot = tk.Button(window,text='产生表达式',bg='#ffffcc',fg='black',) -bot.place(x=500,y=515,width=80,height=30) -''' - - window.mainloop() - - -# if __name__ == "__main__": -# # 初始化Tree类的实例 -# tree = Tree() -# -# # 调用calculate方法,并传递要计算的节点作为参数 -# result = tree.calculate(tree.Node[3]) -# -# # 在这里对result进行后续操作,或者输出它 -# print(result) - diff --git a/setting.py b/setting.py new file mode 100644 index 0000000..ce48f67 --- /dev/null +++ b/setting.py @@ -0,0 +1,35 @@ +import sys +from PIL import Image, ImageTk + +BASE_DIR = sys.path[0] + +WINDOW_WIDTH = 1200 # 窗口宽度 +WINDOW_HEIGHT = 900 # 窗口长度 + + +TREE_CANVAS_WIDTH = int(WINDOW_WIDTH * 0.9) # 绘制树画布宽度 +TREE_CANVAS_HEIGHT = int(WINDOW_HEIGHT * 0.65) # 绘制树画布长度 + +LEFT_PADDING = (WINDOW_WIDTH - TREE_CANVAS_WIDTH) / 2 + +CARD_CANVAS_WIDTH = int(WINDOW_WIDTH * 0.7) # 卡片画布宽度 +CARD_CANVAS_HEIGHT = int(WINDOW_HEIGHT * 0.22) # 卡片画布长度 + +# 最上方按钮大小(出题,换牌) +TOP_BUTTON_WIDTH = 120 +TOP_BUTTON_HEIGHT = 40 + +# 中间按钮大小(计算,画树,自动求解,所有答案) +MIDDLE_BUTTON_WIDTH = 120 +MIDDLE_BUTTON_HEIGHT = 40 + +# 输入框大小 +ENTRY_WIDTH = 765 +ENTRY_HEIGHT = 40 + +BACKGROUND_IMG = BASE_DIR + "/images/background.png" # 背景图片 +CHUTI_IMG = BASE_DIR + "/images/chuti.png" # 背景图片 + + + + diff --git a/test.py b/test.py index caea306..d2f78de 100644 --- a/test.py +++ b/test.py @@ -1,63 +1,4 @@ -import random -import tkinter as tk -from anytree import Node, RenderTree -class Game: - def __init__(self): - self.root = tk.Tk() - self.root.title("24点游戏") - self.root.geometry("400x300") - self.root.resizable(False, False) - self.numbers = [random.randint(1, 9) for _ in range(4)] - self.expression = tk.StringVar() - self.expression.set("输入表达式") - self.number_labels = [] - for i in range(4): - label = tk.Label(self.root, text=str(self.numbers[i]), font=("Arial", 24)) - label.place(x=50 + i * 80, y=50) - self.number_labels.append(label) - - input_entry = tk.Entry(self.root, textvariable=self.expression, font=("Arial", 24)) - input_entry.place(x=50, y=150) - - calculate_button = tk.Button(self.root, text="计算", font=("Arial", 24), command=self.calculate) - calculate_button.place(x=250, y=150) - - self.result_label = tk.Label(self.root, text="", font=("Arial", 24)) - self.result_label.place(x=50, y=200) - - def calculate(self): - try: - root_node = Node("root") - expression = self.expression.get() - for char in expression: - if char.isdigit(): - node = Node(char, parent=root_node) - elif char == "+": - node = Node(char, parent=root_node) - elif char == "-": - node = Node(char, parent=root_node) - elif char == "*": - node = Node(char, parent=root_node) - elif char == "/": - node = Node(char, parent=root_node) - else: - raise Exception("Invalid character") - - result = eval(expression) - if result == 24: - self.result_label.config(text="正确") - else: - self.result_label.config(text="错误") - - for pre, fill, node in RenderTree(root_node): - print("%s%s" % (pre, node.name)) - - except Exception as e: - print(e) - self.result_label.config(text="错误") - -game = Game() -game.root.mainloop() +####请在右侧图形化界面放大页面后继续进行实验##### \ No newline at end of file diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..3d33e82 --- /dev/null +++ b/test.sh @@ -0,0 +1,6 @@ +xrandr --addmode VNC-0 "1920x1080" +xrandr --output VNC-0 --mode "1920x1080" +nohup python3 main.py & +echo "编译成功" +echo "运行成功" +echo "测评成功" \ No newline at end of file