目录
一、项目简介
代码资源在文章最后。
太极生两仪,两仪生四象,四象生八卦。八卦有乾,兑,离,震,巽,坎,艮,坤。
两两相组形成六十四卦,每一卦代表一种状态或过程,每一卦有六爻,爻辞是对该卦中某一爻的情况分析。爻分为阳爻和阴爻,又可有;老阳,老阴,少阳少阴表示其变化。他们是组成卦象的基本单位。本项目以9代表老阳,6代表老阴,7代表少阳,8代表少阴。
项目演示
六爻演示
二、项目实现
1.创建界面
tkinter模块("Tk")是Python 标准的TK GUI工具包的接口。创建一个tkinter 窗口先导入tkinter模块。
导入 tkinter
import tkinter as tk
from tkinter import *
创建一个 大小为600x400的窗口并位置居中于屏幕大小不可改。
import tkinter as tk
window = tk.Tk() # 创建一个窗口
window.title("易哲学") # title 是tkinter创建窗口的标题
# 获取窗口大小
sw = window.winfo_screenwidth()
sh = window.winfo_screenheight()
Width = 400
Hight = 550
# 计算中心坐标
cen_x = (sw - Width) / 2
cen_y = (sh - Hight) / 2
# 设置窗口大小并居中
window.geometry('%dx%d+%d+%d' % (Width, Hight, cen_x, cen_y))
# %dx%d 是窗口大小 等于400*500像素大小
window.resizable(False, False) # 将窗口设置为不可改变大小
text1 = tk.Label(window, text="hello world") # 添加文本
text1 .place(x=62, y=8) # place 是具体坐标
window.mainloop() # 保证窗口一直显示必须要加,否则窗口闪一下就消失。
这样我们可以得到一个不可以改变大小的窗口,为了后续进行转化界面等,我们进行优化封装。将py文件命名为“主程序”(主程序.py),进行类编写如下。
import tkinter as tk
class MainPage(object): # 主界面 包括菜单栏
def __init__(self, master=None):
self.window = master # 定义内部变量window
self.window.title("易哲学")
# 获取屏幕宽度和高度
self.sw = self.window.winfo_screenwidth()
self.sh = self.window.winfo_screenheight()
self.Width = 600
self.High = 400
# 计算中心坐标
self.cen_x = (self.sw - self.Width) / 2
self.cen_y = (self.sh - self.High) / 2
# 设置窗口大小并居中
self.window.geometry('%dx%d+%d+%d' % (self.Width, self.High, self.cen_x, self.cen_y))
self.window.resizable(False, False)
# 排盘界面和首页
self.first_page = FirstFrame()
self.reset_page = ResetFrame()
self.about_page = About()
self.create_page()
def create_page(self): # 首页菜单栏
menubar = tk.Menu(self.window) # 创建菜单栏
menubar.add_command(label='六爻排盘', command=self.first_data)
menubar.add_command(label='关于', command=self.about_date)
menubar.add_command(label='首页', command=self.reset_date)
self.reset_page.pack() # 程序开始运行先进入首页界面
self.window['menu'] = menubar # 设置菜单栏
def first_data(self): # 使界面可以来回切换
self.first_page.pack()
self.reset_page.forget()
self.about_page.forget()
def reset_date(self):
self.reset_page.pack()
self.first_page.forget()
self.about_page.forget()
def about_date(self):
self.about_page.pack()
self.first_page.forget()
self.reset_page.forget()
class FirstFrame(tk.Frame): # 继承Frame类 六爻排盘界面
def __init__(self, master=None):
super().__init__(master)
self.page1()
def page1(self):
tk.Label(self, text='排盘界面').pack()
class About(tk.Frame): # 关于界面 相关资料显示
def __init__(self, master=None):
super().__init__(master)
self.page2()
def page2(self):
tk.Label(self, text='关于界面').pack()
class ResetFrame(tk.Frame): # 继承Frame类 六爻排盘界面
def __init__(self, master=None):
super().__init__(master)
self.page3()
def page3(self):
tk.Label(self, text='首页').pack()
if __name__ == '__main__':
window = tk.Tk()
MainPage(master=window)
window.mainloop()
为了保证我们关闭界面后程序不会在后台运行我们可以加上如下代码在后续新建的界面函数中我们都会加上 on_close 函数
if __name__ == '__main__':
def on_close(): # 退出后关闭进程
window.quit()
window.destroy()
window = tk.Tk()
MainPage(master=window)
window.protocol("WM_DELETE_WINDOW", on_close)
window.mainloop()
2.首页布置
在 class ResetFrame 中是首页相关初始化。在这之前我们需要准备图片资源。
tkinter 中可以使用Label显示图片,本项目将图片转为base码后使用如下:http://t.csdn.cn/cD2BA
import tkinter as tk
import base64
import io
from PIL import ImageTk, Image
class MainPage(object): # 主界面 包括菜单栏
def __init__(self, master=None):
self.window = master # 定义内部变量window
self.window.title("易哲学")
# 获取屏幕宽度和高度
self.sw = self.window.winfo_screenwidth()
self.sh = self.window.winfo_screenheight()
self.Width = 600
self.High = 400
# 计算中心坐标
self.cen_x = (self.sw - self.Width) / 2
self.cen_y = (self.sh - self.High) / 2
# 设置窗口大小并居中
self.window.geometry('%dx%d+%d+%d' % (self.Width, self.High, self.cen_x, self.cen_y))
self.window.resizable(False, False)
# 排盘界面和首页
self.first_page = FirstFrame()
self.reset_page = ResetFrame()
self.about_page = About()
self.create_page()
def create_page(self): # 首页菜单栏
menubar = tk.Menu(self.window) # 创建菜单栏
menubar.add_command(label='六爻排盘', command=self.first_data)
menubar.add_command(label='关于', command=self.about_date)
menubar.add_command(label='首页', command=self.reset_date)
self.reset_page.pack() # 程序开始运行先进入首页界面
self.window['menu'] = menubar # 设置菜单栏
def first_data(self): # 使界面可以来回切换
self.first_page.pack()
self.reset_page.forget()
self.about_page.forget()
def reset_date(self):
self.reset_page.pack()
self.first_page.forget()
self.about_page.forget()
def about_date(self):
self.about_page.pack()
self.first_page.forget()
self.reset_page.forget()
# 图片转码函数资源
def image_back(my_base64_string):
image_bytes = base64.b64decode(my_base64_string)
image_data = io.BytesIO(image_bytes)
my_image = Image.open(image_data)
return my_image
base64_string1 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAIxhI+py+0Po5y02ouz3jz4D4biSJbmiabqyqrcC8fyTNf2PbX6zvf+b8IJh8Si8YgsAAA7"
base64_string2 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAJBhI8XG+kPWYM0soqTzBzsjn0gJY5PaWpXeq6hBMfyTNf2jef6zi/sDwwKh8Si8YhMOnrMpvMJjbqU1Kr1is1qgQUAOw=="
base64_string3 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAI9hI+py+0Po5y02ouz3jz4D4biSJbmiabqyqoRyBlwPHdfDNSbrvGZjwFehImW8YhMKpcmnPMJjUqn1Gq0AAA7"
base64_string4 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAJMhI8XG+kPWYM0soqTzBzsjn0gJY5PaWpXeq6hBMfyTNf2jef6zi8cyjIAg0NWMXU0JUdLULPz/Lkqvar1is1qp8Gu9wsOi8fksrlbAAA7"
base64_string5 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAI8hI+py+0Po5y02ouz3jz4D4biSJbmiabqyqrcC8fyTNf2PbX6zvf+b4qAYMNXsfMhJo1LpEf5ZEadgUgBADs="
base64_string6 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAJLhI8XG+kPWYM0soqTzBzsjn0gJY5PaWpXeq6hBMfyTNf2jef6zi/sDwwKh8Si8YhMOnrMpvMJjboqKGD1d2VlU1tTd/QFhTtjzrgAADs="
base64_string7 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAJHhI+py+0Po5y02ouz3jz4D4biSJbmiabqyqoRyBlwPHdfDNSbrvGZjwFehImW8YhMKpem1432tHlwxEqVcp1kJVvnFPp9FAAAOw=="
base64_string8 = "R0lGODlhHgAoAPABAAQEBP///yH5BAAAAAAALAAAAAAeACgAAAJVhI8XG+kPWYM0soqTzBzsjn0gJY5PaWpXeq6hBMfyTNf2jef6zi8cyjIAg0NWMXU0JUdLULPz/Lkqvar1is1qpyRu0OMlho1jZFl5Zqada2hb6ssUAAA7"
picture1 = image_back(my_base64_string=base64_string1)
picture2 = image_back(my_base64_string=base64_string2)
picture3 = image_back(my_base64_string=base64_string3)
picture4 = image_back(my_base64_string=base64_string4)
picture5 = image_back(my_base64_string=base64_string5)
picture6 = image_back(my_base64_string=base64_string6)
picture7 = image_back(my_base64_string=base64_string7)
picture8 = image_back(my_base64_string=base64_string8)
picture9 = image_back(my_base64_string=base64_string9)
class FirstFrame(tk.Frame): # 继承Frame类 六爻排盘界面
def __init__(self, master=None):
super().__init__(master)
self.page1()
def page1(self):
tk.Label(self, text='排盘界面').pack()
class About(tk.Frame): # 关于界面 相关资料显示
def __init__(self, master=None):
super().__init__(master)
self.page2()
def page2(self):
tk.Label(self, text='关于界面').pack()
class ResetFrame(tk.Frame): # 继承Frame类 六爻排盘界面
def __init__(self, master=None):
super().__init__(master)
self.window_reset = master
self.picture1 = ImageTk.PhotoImage(picture1)
self.picture2 = ImageTk.PhotoImage(picture2)
self.picture3 = ImageTk.PhotoImage(picture3)
self.picture4 = ImageTk.PhotoImage(picture4)
self.picture5 = ImageTk.PhotoImage(picture5)
self.picture6 = ImageTk.PhotoImage(picture6)
self.picture7 = ImageTk.PhotoImage(picture7)
self.picture8 = ImageTk.PhotoImage(picture8)
self.picture9 = ImageTk.PhotoImage(picture9)
self.create_page3()
def create_page3(self):
# 创建画布,在画布上显示图片资源
canvas = tk.Canvas(self, bg='white', height=400, width=600)
canvas.create_text(290, 10, text="首页", anchor='nw')
canvas.create_text(100, 40, text="乾一\t兑二\t离三\t震四\t巽五\t坎六\t艮七\t坤八", anchor='nw')
canvas.create_image(110, 80, image=self.picture1)
canvas.create_image(168, 80, image=self.picture2)
canvas.create_image(225, 80, image=self.picture3)
canvas.create_image(282, 80, image=self.picture4)
canvas.create_image(337, 80, image=self.picture5)
canvas.create_image(394, 80, image=self.picture6)
canvas.create_image(448, 80, image=self.picture7)
canvas.create_image(506, 80, image=self.picture8)
canvas.create_image(310, 220, image=self.picture9)
canvas.pack()
if __name__ == '__main__':
window = tk.Tk()
MainPage(master=window)
window.mainloop()
base64_string9(picture9)的资源过长,不在上代码里。文章最后获取源码。运行后首页界面如下:
3.关于界面布置
关于界面是一些相关的内容查看
界面上的按钮是跳转界面按钮,为了清晰且可以打开多个界面,我们会创建另一个界面函数用于显示内容,下文会提起。class About 的代码如下
class About(tk.Frame): # 关于界面 相关资料显示
def __init__(self, master=None):
super().__init__(master)
self.page()
def page(self):
def page_1(): # 象数易理一
pass
def page_2(): # 象数易理二
pass
def page_3(): # 三-八卦类象
pass
def page_31(): # 一金
pass
def page_32():
pass
def page_33():
pass
def page_34():
pass
def page_35():
pass
def page_36():
pass
def page_37():
pass
def page_38():
pass
canvas = tk.Canvas(self, bg='white', width=600, height=400)
# 在window上创建一个canvas显示界面内容
canvas.create_text(275, 10, text='相关信息', anchor='nw', font=20)
tk.Button(self, text='象数易理一', command=page_1).place(x=160, y=50)
tk.Button(self, text='象数易理二', command=page_2).place(x=270, y=50)
tk.Button(self, text='象数易理三', command=page_3).place(x=380, y=50)
canvas.create_line(200, 120, 200, 145) # 界面上画的线
canvas.create_line(410, 90, 410, 145)
canvas.create_line(200, 120, 410, 120)
canvas.create_text(280, 100, text='八卦万物属类', anchor='nw')
tk.Button(self, text='一 金', command=page_31).place(x=180, y=150)
tk.Button(self, text='二 金', command=page_32).place(x=250, y=150)
tk.Button(self, text='三 水', command=page_33).place(x=320, y=150)
tk.Button(self, text='四 木', command=page_34).place(x=390, y=150)
tk.Button(self, text='五 木', command=page_35).place(x=180, y=200)
tk.Button(self, text='六 水', command=page_36).place(x=250, y=200)
tk.Button(self, text='七 土', command=page_37).place(x=320, y=200)
tk.Button(self, text='八 土', command=page_38).place(x=390, y=200)
canvas.pack()
如上我们创建了带有按钮的界面,现在我们点击按钮是没有任何反应的。而显示内容的界面可以是一样的,所以我们可以创建一个通用的显示关于界面文本的函数显。放到class About 外。
点击按钮后传入数据显示结果即可。
def page_x(head): # 创建通用界面函数,输出内容不同
def on_close3():
window_about_page1.quit()
try: # 异常处理
window_about_page1.destroy()
except NameError:
pass
window_about_page1 = tk.Tk() # 创建一个新界面显示文本内容
window_about_page1.title('象数易理')
sw = window_about_page1.winfo_screenwidth()
sh = window_about_page1.winfo_screenheight()
cen_x = (sw - 500) / 2
cen_y = (sh - 400) / 2
window_about_page1.geometry('%dx%d+%d+%d' % (500, 400, cen_x, cen_y))
window_about_page1.resizable(False, False)
my_text = tk.Text(window_about_page1, font=('楷体', 15),
# bg='#ccffff',
width=500, height=400, )
# 插入文本1
text_x = head
my_text.insert(tk.INSERT, text_x)
my_text.config(state='disabled') # 设置内容不可编辑
scroll_y = tk.Scrollbar(window_about_page1) # 创建右侧滚动条
scroll_y.pack(side=tk.RIGHT, fill=tk.Y) # 放到窗体的右侧 沿Y轴平铺
my_text.pack(side=tk.RIGHT, fill=tk.Y)
# 关联文本控件
scroll_y.config(command=my_text.yview)
my_text.config(yscrollcommand=scroll_y.set)
window_about_page1.protocol("WM_DELETE_WINDOW", on_close3)
window_about_page1.mainloop()
head为传入的数据
resource 为导入资源文章最后获取
class About 内的page函数:
def page(self):
def page_1(): # 象数易理一
page_x(head=resource.head1)
def page_2(): # 象数易理二
page_x(head=resource.head2)
def page_3(): # 三-八卦类象
page_x(head=resource.head3)
def page_31(): # 一金
page_x(head=resource.head31)
def page_32():
page_x(head=resource.head32)
def page_33():
page_x(head=resource.head33)
def page_34():
page_x(head=resource.head34)
def page_35():
page_x(head=resource.head35)
def page_36():
page_x(head=resource.head36)
def page_37():
page_x(head=resource.head37)
def page_38():
page_x(head=resource.head38)
这是关于界面的布置已经做好了,将resource.py文件放到与主文件同一目录下,导入即可
import resource
4.排盘界面的布置
4.1界面
排盘界面的布置 会使用到tkinter 中的buttun 和Entay 。输入的数字或通过get 获取。通过random 模块进行随机输入。
class FirstFrame 代码如下
class FirstFrame(tk.Frame): # 继承Frame类 六爻排盘界面
def __init__(self, master=None):
super().__init__(master)
self.x1, self.x2 = None, None
self.G = None
self.text_x1 = None
self.window = master
self.s2, self.s1, self.list2, self.list1 = None, None, None, None
self.n1, self.n2, self.n3, = tk.StringVar(), tk.StringVar(), tk.StringVar()
self.n4, self.n5, self.n6 = tk.StringVar(), tk.StringVar(), tk.StringVar()
self.create_first_page()
def create_first_page(self): # 显示输入框函数
tk.Button(self, text='确定', font=25, width=8, command=self.change).pack()
tk.Label(self, text='上 爻: ').pack()
tk.Entry(self, textvariable=self.n6).pack()
tk.Label(self, text='五 爻: ').pack()
tk.Entry(self, textvariable=self.n5).pack()
tk.Label(self, text='四 爻: ').pack()
tk.Entry(self, textvariable=self.n4).pack()
tk.Label(self, text='三 爻: ').pack()
tk.Entry(self, textvariable=self.n3).pack()
tk.Label(self, text='二 爻: ').pack()
tk.Entry(self, textvariable=self.n2).pack()
tk.Label(self, text='初 爻: ').pack()
tk.Entry(self, textvariable=self.n1).pack()
tk.Label(self, text="从下往上依次输入数字6,7,8,9中的一个\n6为老阴9为老阳,"
"7为少阳8为少阴\n输入其他内容显示错误").pack()
tk.Button(self, text='重置', font=35, height=2, width=8, command=self.reset_date).pack(side='left')
tk.Button(self, text='随机', font=35, height=2, width=8, command=self.random_date).pack(side='right')
def reset_date(self):
pass
def random_date(self):
pass
def change(self):
pass
4.2重置
x1,x2,G,,text_x1 为change函数值。接下来先填写reset_date函数内容,我们手动输入内容后点击重置可以清空内容,就是在文本框插入空内容。
def reset_date(self): # 重置内容框插入空值
self.n6.set(''), self.n5.set(''), self.n4.set('')
self.n3.set(''), self.n2.set(''), self.n1.set('')
4.3随机
random_date 函数是随机插入6到9的数字,需要先导入模块
import random
后续判断具体卦象需要将数转为字符串。
def random_date(self): # 插入随机值
v6, v5, v4 = random.randint(6, 9), random.randint(6, 9), random.randint(6, 9)
v3, v2, v1 = random.randint(6, 9), random.randint(6, 9), random.randint(6, 9)
self.n6.set(str(v6)), self.n5.set(str(v5)), self.n4.set(str(v4)),
self.n3.set(str(v3)), self.n2.set(str(v2)), self.n1.set(str(v1))
4.4确定
(1)判断条件
输入的值都是6到9的数值,确保我们输入的值正确先要创建一个6,7,8,9组成的3位数,当上卦(下文以s1表示)、下卦(s2)都在这个列表表示输入正确进行下一步,否则输入错误。
L = []
ld = [7, 9]
ls = [6, 8]
for i in range(6, 10): # 创建并遍历6到9的数
for j in range(6, 10): # 创建并遍历6到9的数
for k in range(6, 10): # 创建并遍历6到9的数
s = '' # 每次重置字符串保证每次加进去的都是3位数
i = str(i) # 将整型转为字符串
j = str(j)
k = str(k)
s += ''.join(i) # 分别将i,j,k添加
s += ''.join(j)
s += ''.join(k)
L.append(s) # 将i,j,k组成的三位数添加到列表里
一卦可以由3个数表示即
ld = [7, 9]
ls = [6, 8]
l1 = [] # 乾
for i in ld:
for j in ld:
for k in ld:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l1.append(s)
l2 = [] # 兑
for i in ls:
for j in ld:
for k in ld:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l2.append(s)
l3 = [] # 离
for i in ld:
for j in ls:
for k in ld:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l3.append(s)
l4 = [] # 震
for i in ls:
for j in ls:
for k in ld:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l4.append(s)
l5 = [] # 巽
for i in ld:
for j in ld:
for k in ls:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l5.append(s)
l6 = [] # 坎
for i in ls:
for j in ld:
for k in ls:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l6.append(s)
l7 = [] # 艮
for i in ld:
for j in ls:
for k in ls:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l7.append(s)
l8 = [] # 坤
for i in ls:
for j in ls:
for k in ls:
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
l8.append(s)
ln = [] # 没有变卦,及没有9,6组成
for i in range(7, 9):
for j in range(7, 9):
for k in range(7, 9):
s = ''
i = str(i)
j = str(j)
k = str(k)
s += ''.join(i)
s += ''.join(j)
s += ''.join(k)
ln.append(s)
change 函数 如下
def change(self): # 点击确定后函数
# 获取输入内容转为str类型
self.s1, self.s2 = '', ''
self.list1 = [self.n6.get(), self.n5.get(), self.n4.get()] # 上
self.list2 = [self.n3.get(), self.n2.get(), self.n1.get()] # 下
for i in self.list1:
i = str(i)
self.s1 += ''.join(i)
for j in self.list2:
j = str(j)
self.s2 += ''.join(j)
if self.s1 and self.s2 in resource.L: # 判断是否输入正确 错误提示,不管有没有变卦都进入。
print("yes")
else: # 输入错误弹窗
tk.messagebox.showerror(title='提示', message='输入错误')
当输入错误会出现提示,使用提示弹窗,需要导入模块
import tkinter.messagebox
change 函数 还需要进行判断具体卦象
卦由上下两部分组成,一爻用一个数字代表,假设没有变卦的乾卦即为(777777),上下由八卦两两组成64卦,我们将上3数组成一组,下3数组成一组,分别代表某一卦。
上文中提到过s1,s2,当输入正确进入判断卦象阶段。为了便于理解本项目使用大量if else判断情况,两两组成一个卦象,即可先确定上卦后与其他八卦(下卦)在匹配组成。当上卦为乾时,下卦可以是(乾,兑,离,震,巽,坎,艮,坤),上卦也有八种变化即可得64卦。依次类推应当有八组下列类似代码。下文不在重复累述,仅以上为乾举例。
if self.s1 in resource.l1: # 为便于理解用多重if elif 判断结果
if self.s2 in resource.l1: # 当s1是乾时,s2还有8种结果,依此类推共64卦
print("上乾下乾")
elif self.s2 in resource.l2:
print("上乾下兑")
elif self.s2 in resource.l3:
print("上乾下离")
elif self.s2 in resource.l4:
print("上乾下震")
elif self.s2 in resource.l5:
print("上乾下巽")
elif self.s2 in resource.l6:
print("上乾下坎")
elif self.s2 in resource.l7:
print("上乾下艮")
elif self.s2 in resource.l8:
print("上乾下坤")
(2)没有变卦
确定好具体卦后需要输出具体内容,先以没有变卦为例(没有变卦即为输入的数字没有6或者9的情况,老阳和老阴可以理解为物极必反需要变化,阳变为阴,阴变为阳。)输出具体内容需同上问关于界面一样创建一个新的界面显示内容。在 class FirstFrame(tk.Frame)外 创建一个函数。并对change函数修改。
# 没有变卦函数
def result(g1, x1, x2, text_x1): # g1:卦词内容,x1:上卦图片,x2:下卦图片,text:卦象
def on_close1(): # 当关闭窗口后退出进程
window_result.quit()
try: # 异常处理
window_result.destroy()
except NameError:
pass
window_result = tk.Tk() # 创建一个新窗口显示结果。
window_result.withdraw() # 实现窗口隐藏
window_result = tk.Toplevel()
window_result.title('结果')
sw = window_result.winfo_screenwidth() # 获取屏幕宽高
sh = window_result.winfo_screenheight()
cen_x = (sw - 500) / 2
cen_y = (sh - 400) / 2
window_result.geometry('%dx%d+%d+%d' % (500, 400, cen_x, cen_y))
window_result.resizable(False, False)
p1 = ImageTk.PhotoImage(x1) # p1,p2 图片赋值
p2 = ImageTk.PhotoImage(x2)
text_g = text_x1
tk.Label(window_result, text=text_g).pack()
tk.Label(window_result, image=p1).pack()
tk.Label(window_result, image=p2).pack()
my_text = tk.Text(window_result, font=('楷体', 15),
# bg='#ccffff',
width=500, height=250, )
my_text.pack(pady=(20, 5))
# 插入文本1
text_x = g1
my_text.insert(tk.INSERT, text_x)
my_text.config(state='disabled') # 设置内容不可编辑
scroll_y = tk.Scrollbar(window_result) # 创建右侧滚动条
scroll_y.pack(side=tk.RIGHT, fill=tk.Y) # 放到窗体的右侧 沿Y轴平铺
my_text.pack(side=tk.RIGHT, fill=tk.Y)
# 关联文本控件
scroll_y.config(command=my_text.yview)
my_text.config(yscrollcommand=scroll_y.set)
window_result.protocol("WM_DELETE_WINDOW", on_close1)
window_result.mainloop()
上述判断情况的代码换为:
if self.s1 in resource.l1: # 为便于理解用多重if elif 判断结果
if self.s2 in resource.l1: # 当s1是乾时,s2还有8种结果,依此类推共64卦
self.G = resource.G1 # 赋值为存在变卦准备
self.x1 = picture1
self.x2 = picture1
self.text_x1 = resource.text1
if self.s1 in resource.ln and self.s2 in resource.ln: # 没有变卦,及没有9,6组成,判断是否在ln列表中
result(g1=resource.G1, x1=picture1, x2=picture1, text_x1=resource.text1)
elif self.s2 in resource.l2:
self.G = resource.G10
self.x1 = picture1
self.x2 = picture2
self.text_x1 = resource.text10
if self.s1 in resource.ln and self.s2 in resource.ln:
result(g1=resource.G10, x1=picture1, x2=picture2, text_x1=resource.text10)
elif self.s2 in resource.l3:
self.G = resource.G13
self.x1 = picture1
self.x2 = picture3
self.text_x1 = resource.text13
if self.s1 in resource.ln and self.s2 in resource.ln:
result(g1=resource.G13, x1=picture1, x2=picture3, text_x1=resource.text13)
elif self.s2 in resource.l4:
self.G = resource.G25
self.x1 = picture1
self.x2 = picture4
self.text_x1 = resource.text25
if self.s1 in resource.ln and self.s2 in resource.ln:
result(g1=resource.G25, x1=picture1, x2=picture4, text_x1=resource.text25)
elif self.s2 in resource.l5:
self.G = resource.G44
self.x1 = picture1
self.x2 = picture5
self.text_x1 = resource.text44
if self.s1 in resource.ln and self.s2 in resource.ln:
result(g1=resource.G44, x1=picture1, x2=picture5, text_x1=resource.text44)
elif self.s2 in resource.l6:
self.G = resource.G6
self.x1 = picture1
self.x2 = picture6
self.text_x1 = resource.text6
if self.s1 in resource.ln and self.s2 in resource.ln:
result(g1=resource.G6, x1=picture1, x2=picture6, text_x1=resource.text6)
elif self.s2 in resource.l7:
self.G = resource.G33
self.x1 = picture1
self.x2 = picture7
self.text_x1 = resource.text33
if self.s1 in resource.ln and self.s2 in resource.ln:
result(g1=resource.G33, x1=picture1, x2=picture7, text_x1=resource.text33)
elif self.s2 in resource.l8:
self.G = resource.G12
self.x1 = picture1
self.x2 = picture8
self.text_x1 = resource.text12
if self.s1 in resource.ln and self.s2 in resource.ln:
result(g1=resource.G12, x1=picture1, x2=picture8, text_x1=resource.text12)
即可以得到输出没有变卦的界面
(3)存在变卦
当存在变卦时,需要将6变为7.9变为8。先将通用显示函数写出放到class FiestFrame 外,存在变卦时需要显示两个文本信息和卦象,因此需要创建两个Frame来显示并进行切换。当我们切换时需要将另一个Frame(1)销毁在显示另一个Frame(2)。当程序启动时Frame(2)并没有创建出来过(默认先显示Frame(1)),所以需要进行异常处理,如遇到异常可以跳过执行,异常语句不再在本处介绍。
# 存在变卦函数
global frame2, frame1 # 全局变量
def result_r(g1, g2, x1, x2, x11, x22, text_x1, text_x2):
def create_frame1(): # 显示本卦文本函数
global frame2, frame1
try: # 异常处理,
frame1.destroy()
except NameError:
pass
finally:
try:
frame2.destroy()
except NameError:
pass
finally:
# 创建新容器显示内容
frame1 = tk.Frame(window_result, height=250, width=500)
frame1.pack()
frame1.pack_propagate()
my_text = tk.Text(frame1, font=('楷体', 15),
# bg='#ccffff',
width=500, height=250, )
my_text.pack(pady=(20, 5))
# 插入文本1
text_x = g1
my_text.insert(tk.INSERT, text_x)
my_text.config(state='disabled') # 设置内容不可编辑
scroll_y = tk.Scrollbar(frame1) # 创建右侧滚动条
scroll_y.pack(side=tk.RIGHT, fill=tk.Y) # 放到窗体的右侧 沿Y轴平铺
my_text.pack(side=tk.RIGHT, fill=tk.Y)
# 关联文本控件
scroll_y.config(command=my_text.yview)
my_text.config(yscrollcommand=scroll_y.set)
def create_frame2(): # 变卦界面
global frame2, frame1
try:
frame1.destroy()
except NameError:
pass
finally:
try:
frame2.destroy()
except NameError:
pass
finally:
frame2 = tk.Frame(window_result, height=600, width=500, )
frame2.pack()
frame2.pack_propagate()
my_text = tk.Text(frame2, font=('楷体', 15),
# bg='#ccffff',
width=500, height=250, )
my_text.pack(pady=(20, 5))
# 插入文本1
text_x = g2
my_text.insert(tk.INSERT, text_x)
my_text.config(state='disabled') # 设置内容不可编辑
scroll_y = tk.Scrollbar(frame2) # 创建右侧滚动条
scroll_y.pack(side=tk.RIGHT, fill=tk.Y) # 放到窗体的右侧 沿Y轴平铺
my_text.pack(side=tk.RIGHT, fill=tk.Y)
# 关联文本控件
scroll_y.config(command=my_text.yview)
my_text.config(yscrollcommand=scroll_y.set)
def on_close2():
window_result.quit()
try:
window_result.destroy()
except NameError:
pass
window_result = tk.Tk() # 创建一个新窗口显示结果。
window_result.withdraw()
window_result = tk.Toplevel()
window_result.title('结果')
sw = window_result.winfo_screenwidth()
sh = window_result.winfo_screenheight()
cen_x = (sw - 500) / 2
cen_y = (sh - 400) / 2
window_result.geometry('%dx%d+%d+%d' % (500, 400, cen_x, cen_y))
window_result.resizable(False, False)
# 显示卦象的容器
frame0 = tk.Frame(window_result, height=150, width=400)
frame0.pack()
text_self = text_x1
text_chang = text_x2
p1 = ImageTk.PhotoImage(x1) # p1,p2 图片赋值
p2 = ImageTk.PhotoImage(x2)
p11 = ImageTk.PhotoImage(x11)
p22 = ImageTk.PhotoImage(x22)
tk.Label(frame0, text=text_self).place(x=130, y=2)
tk.Label(frame0, image=p1).place(x=140, y=25)
tk.Label(frame0, image=p2).place(x=140, y=70)
btn1 = tk.Button(frame0, text='本卦', command=create_frame1)
btn1.place(x=140, y=115)
tk.Label(frame0, text=text_chang).place(x=210, y=2)
tk.Label(frame0, image=p11).place(x=220, y=25)
tk.Label(frame0, image=p22).place(x=220, y=70)
btn2 = tk.Button(frame0, text='变卦', command=create_frame2)
btn2.place(x=220, y=115)
create_frame1() # 开始显示本卦界面
window_result.protocol("WM_DELETE_WINDOW", on_close2)
window_result.mainloop()
上述为存在变卦的显示文本函数,而存在变卦时输入包含9或6,判断卦象是根据输入的数字判断在哪一个列表。所以需要在第一个判断(if self.s1 and self.s2 in resource.L: # 判断是否输入正确 错误提示,不管有没有变卦都进入。)后在进行一次判断,如果存在变卦进入,否则跳过。此时需要将6替换为7,9替换为8,用(replace)即可:(以上乾为例)
if self.s1 not in resource.ln or self.s2 not in resource.ln:
# 上个条件若输入正确,无论是否有都实现当没有变卦没有变卦界面运行,
# 此条件为没有变卦,及s1 or s2 其中一个不在ln(没有9,6组成的列表)执行
n1 = self.list1.count('6') # 替换字符串、replace 函数。
n2 = self.list1.count('9') # 分别替换s1、s2 n 为要替换次数
n3 = self.list2.count('6')
n4 = self.list2.count('9')
self.s1 = self.s1.replace('6', '7', n1) # 确定替换次数及替换对象
self.s1 = self.s1.replace('9', '8', n2)
self.s2 = self.s2.replace('6', '7', n3)
self.s2 = self.s2.replace('9', '8', n4)
if self.s1 in resource.l1: # 原理同上判断具体卦
if self.s2 in resource.l1:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G1, x11=picture1, x22=picture1, text_x2=resource.text1)
elif self.s2 in resource.l2:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G10, x11=picture1, x22=picture2, text_x2=resource.text10)
elif self.s2 in resource.l3:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G13, x11=picture1, x22=picture3, text_x2=resource.text13)
elif self.s2 in resource.l4:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G25, x11=picture1, x22=picture4, text_x2=resource.text44)
elif self.s2 in resource.l5:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G44, x11=picture1, x22=picture5, text_x2=resource.text44)
elif self.s2 in resource.l6:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G6, x11=picture1, x22=picture6, text_x2=resource.text6)
elif self.s2 in resource.l7:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G33, x11=picture1, x22=picture7, text_x2=resource.text33)
elif self.s2 in resource.l8:
result_r(g1=self.G, x1=self.x1, x2=self.x2, text_x1=self.text_x1,
g2=resource.G12, x11=picture1, x22=picture8, text_x2=resource.text12)
5.打包py文件
在pycharm终端中操作即可,
第一步 使用命令进入到打包文件的文件夹路径(打包后保存位置)。
示例在桌面创建了一个文件夹。
第二步使用pyinstaller 打包
在此之前先安装pyinstaller(省略)
代码示例
pyinstaller -F -w -i 图标路径地址 文件路径地址
打包完成后会在文件夹里生成dist 文件 exe文件在里面,双击运行即可。
以上本项目基本结构已完,具体内容请获取文件资源。
三、项目资源
本项目使用较简单的方法实现,存在一定缺陷,欢迎交流指点。
链接:https://pan.baidu.com/s/15e_2CQR9iKENMztid_yFkg
提取码:r8ea