用Python tkinter 写一个六十四卦象算卦代码并打包为exe文件

目录

一、项目简介

二、项目实现

1.创建界面

2.首页布置

3.关于界面布置


一、项目简介

        代码资源在文章最后

        太极生两仪,两仪生四象,四象生八卦。八卦有乾,兑,离,震,巽,坎,艮,坤。

        两两相组形成六十四卦,每一卦代表一种状态或过程,每一卦有六爻,爻辞是对该卦中某一爻的情况分析。爻分为阳爻和阴爻,又可有;老阳,老阴,少阳少阴表示其变化。他们是组成卦象的基本单位。本项目以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 
 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
这是一篇完整的Python Tkinter查重软件教程,我将引导你完成一个查重软件的创建。在这个教程中,我们将学习如何使用PythonTkinter模块创建GUI,如何使用Python的hashlib模块计算文件的哈希值,并且如何比较两个文件的哈希值。 1.导入Python Tkinter模块 首先,我们需要导入PythonTkinter模块,这个模块是Python的标准GUI库。我们可以使用以下代码导入Tkinter模块: import tkinter as tk 2.创建GUI窗口 接下来,我们需要创建一个GUI窗口,让用户可以选择要比较的文件。我们可以使用以下代码创建一个GUI窗口: win = tk.Tk() win.title("查重软件") win.geometry("400x300") win.resizable(False, False) 这里我们创建了一个名为“查重软件”的窗口,并设置了窗口的大小和是否可调整大小。 3.添加GUI控件 接下来,我们需要向窗口添加一些GUI控件,以便用户可以选择要比较的文件。我们可以使用以下代码向窗口添加一个按钮和一个标签: label = tk.Label(win, text="选择要比较的文件:", font=("Helvetica", 12)) label.pack(pady=10) button = tk.Button(win, text="选择文件", command=select_file) button.pack(pady=10) 这里我们创建了一个标签,用于提示用户选择要比较的文件,以及一个按钮,用于触发选择文件的操作。在按钮上,我们还指定了一个回调函数select_file,以便用户选择文件后进行处理。 4.定义选择文件的函数 接下来,我们需要定义select_file函数,以便用户选择要比较的文件。我们可以使用以下代码定义select_file函数: def select_file(): file_path = tk.filedialog.askopenfilename() if file_path: file_hash = calculate_hash(file_path) compare_hash(file_hash) 这里我们使用了tkinter文件对话框,让用户可以选择要比较的文件。如果用户选择了一个文件,我们就计算文件的哈希值,并比较该文件的哈希值与其他文件的哈希值。 5.计算文件的哈希值 接下来,我们需要计算文件的哈希值。我们可以使用Python的hashlib模块计算文件的哈希值。我们可以使用以下代码定义calculate_hash函数: import hashlib def calculate_hash(file_path): with open(file_path, "rb") as f: file_data = f.read() file_hash = hashlib.md5(file_data).hexdigest() return file_hash 这里我们打开要比较的文件,并使用hashlib模块计算文件的MD5哈希值,并将哈希值以字符串形式返回。 6.比较文件的哈希值 接下来,我们需要比较文件的哈希值。我们可以使用Python的字典数据结构来存储所有已经比较过的文件的哈希值。我们可以使用以下代码定义compare_hash函数: file_dict = {} def compare_hash(file_hash): if file_hash in file_dict: print("该文件已经存在:", file_dict[file_hash]) else: file_dict[file_hash] = file_path print("该文件是新文件。") 这里我们使用一个字典数据结构来存储已经比较过的文件的哈希值。如果该哈希值已经存在于字典中,我们就说明该文件已经存在,否则我们就将该哈希值添加到字典中,并说明该文件一个文件。 7.运行GUI窗口 最后,我们需要运行GUI窗口,让用户可以与程序交互。我们可以使用以下代码运行GUI窗口: win.mainloop() 这里我们使用mainloop()方法运行GUI窗口,并启动事件循环,以便用户可以与程序交互。 完整代码: import tkinter as tk import tkinter.filedialog import hashlib win = tk.Tk() win.title("查重软件") win.geometry("400x300") win.resizable(False, False) label = tk.Label(win, text="选择要比较的文件:", font=("Helvetica", 12)) label.pack(pady=10) button = tk.Button(win, text="选择文件", command=select_file) button.pack(pady=10) file_dict = {} def select_file(): file_path = tk.filedialog.askopenfilename() if file_path: file_hash = calculate_hash(file_path) compare_hash(file_hash, file_path) def calculate_hash(file_path): with open(file_path, "rb") as f: file_data = f.read() file_hash = hashlib.md5(file_data).hexdigest() return file_hash def compare_hash(file_hash, file_path): if file_hash in file_dict: print("该文件已经存在:", file_dict[file_hash]) else: file_dict[file_hash] = file_path print("该文件是新文件。") win.mainloop()

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值