
Python Tkinter 哲学家问题可视化
效果总归还行吧,代码也比较简短,只有170行。再此推荐你看我之前关于这个题目的文章,接下来我直接代码讲解了。
发布日期:2021-05-08 20:30:48
浏览次数:18
分类:精选文章
本文共 7344 字,大约阅读时间需要 24 分钟。
Python Tkinter 哲学家问题可视化
学校的课设总算是告一段落,现在有时间分享一下代码和心得了。这次的文章是回应之前的雏形版代码的,这次的可是完全版哦。
我们先来看一下效果吧!
# -*- coding:utf-8 -*-#print('资源加载中,稍等片刻……')from tkinter import *from PIL import Image,ImageTk from threading import Thread,Lockfrom time import sleepfrom random import randint"""哲学家类"""class Philosopher(Thread): def __init__(self, index,forks,numForks,labels): Thread.__init__(self) self.index = index self.forks=forks self.numForks=numForks self.rightFork = forks[self.index] self.leftFork = forks[(self.index + 1) % numForks] self.bm_thinking=ImageTk.PhotoImage(Image.open('img/thinking.png').resize((150,150),Image.ANTIALIAS)) self.bm_eating=ImageTk.PhotoImage(Image.open('img/eating.png').resize((150,150),Image.ANTIALIAS)) self.bm_waiting=ImageTk.PhotoImage(Image.open('img/waiting.png').resize((150,150),Image.ANTIALIAS)) self.bm_another=ImageTk.PhotoImage(Image.open('img/another.png').resize((150,150),Image.ANTIALIAS)) def run(self): while True: self.thinking() self.hungry() while True: sleep(0.5) if hobby.get()==True:#获取按钮的状态 self.leftFork.pickup() labels[self.index].configure(image=self.bm_another) labels[self.index].image=self.bm_another text.insert(END,"Philosopher %s pick up left Fork.\n"%(self.index)) sleep(0.5) self.rightFork.pickup() text.insert(END,"Philosopher %s pick up right Fork.\n"%(self.index)) self.dining() self.leftFork.putdown() text.insert(END,"Philosopher %s put down left Fork.\n"%(self.index)) self.rightFork.putdown() text.insert(END,"Philosopher %s put down right Fork.\n"%(self.index)) break else: if self.leftFork.use==False: if self.rightFork.use==False: self.leftFork.pickup() text.insert(END,"Philosopher %s pick up left Fork.\n"%(self.index)) self.rightFork.pickup() text.insert(END,"Philosopher %s pick up right Fork.\n"%(self.index)) self.dining() self.leftFork.putdown() text.insert(END,"Philosopher %s put down left Fork.\n"%(self.index)) self.rightFork.putdown() text.insert(END,"Philosopher %s put down right Fork.\n"%(self.index)) break def dining(self): text.insert(END,"Philosopher %s starts to eat.\n"%(self.index)) labels[self.index].configure(image=self.bm_eating) labels[self.index].image=self.bm_eating sleep(randint(2,4)) text.insert(END,"Philosopher %s finishes eating.\n"%(self.index)) def thinking(self): text.insert(END,"Philosopher %s is thinking.\n"%(self.index)) labels[self.index].configure(image=self.bm_thinking) labels[self.index].image=self.bm_thinking if not hobby2.get():#获取按钮的状态 sleep(randint(2,5)) def hungry(self): text.insert(END,"Philosopher %s is hungry.\n"%(self.index)) labels[self.index].configure(image=self.bm_waiting) labels[self.index].image=self.bm_waiting sleep(1)
python图形化的特点,写代码的时候要和Tkinter里的组件结合,所以有时候会不知道类里的使用到的组件是哪来的,可以回到主程序里寻找。
"""叉子类"""class Fork: def __init__(self, index,label_forks): self.index = index self.forks=label_forks self._lock = Lock() self.bm_fork=ImageTk.PhotoImage(Image.open('img/fork.png').resize((70,130),Image.ANTIALIAS)) self.bm_nothing=ImageTk.PhotoImage(Image.open('img/nothing.png').resize((70,130),Image.ANTIALIAS)) self.use=False for i in self.forks: i.configure(image=self.bm_fork) def pickup(self): """叉子的消失其实就是拿一张和背景色相同的图片来遮挡叉子的图片""" self._lock.acquire() self.use=True self.forks[self.index].configure(image=self.bm_nothing) self.forks[self.index].image=self.bm_nothing def putdown(self): self._lock.release() self.use=False self.forks[self.index].configure(image=self.bm_fork) self.forks[self.index].image=self.bm_fork
def main(): text.delete('0.0','end')#清除文本框中的所有内容 numPhilosophers = numForks = 5 # 创建叉子与哲学家实例 forks = [Fork(idx,label_forks) for idx in range(numForks)] philosophers = [Philosopher(idx,forks,numForks,labels)for idx in range(numPhilosophers)] # 开启所有的哲学家线程 for philosopher in philosophers: philosopher.start()
def author():#关于作者的说明,我没有用文本形式而是图片呈现"""必要一提的就是Tkinter不支持二级窗口呈现图片,所以要用Toplevel""" newroot=Toplevel() bm_about = ImageTk.PhotoImage(Image.open('img/about.png')) aboutme=Label(newroot,image=bm_about) aboutme.pack() newroot.mainloop()def detail_show():#“说明”的内容 newroot2=Toplevel() bm_details = ImageTk.PhotoImage(Image.open('img/details.png')) details_label=Label(newroot2,image=bm_details) details_label.pack() newroot2.mainloop()
if __name__ == '__main__': root = Tk() root.title('哲学家问题') root.geometry('1000x750') start=Button(root,text='开始',font=('Arial',12),command=main,relief='raised') start.place(x=100,y=0) tip=Button(root,text='关于',font=('Arial',12),command=author,relief='raised') tip.place(x=180,y=0) hobby=BooleanVar() isDeathLock=Checkbutton(root,text='允许死锁',font=('Arial',12),variable=hobby,relief='raised') isDeathLock.place(x=260,y=0) hobby2=BooleanVar() death=Checkbutton(root,text='饥饿模式',font=('Arial',12),variable=hobby2,relief='raised') death.place(x=400,y=0) details=Button(root,text='说明',font=('Arial',12),command=detail_show,relief='raised') details.place(x=550,y=0) scroll = Scrollbar() text=Text(root,width=35,height=50) scroll.pack(side=RIGHT,fill=Y) text.pack(side=RIGHT) scroll.config(command=text.yview) text.config(yscrollcommand=scroll.set) img_init = Image.open('img/init.png').resize((150,150),Image.BILINEAR) bm_init=ImageTk.PhotoImage(img_init) labels=[] for i in range(5): temp=Label(root,image=bm_init) labels.append(temp) labels[0].place(x=400,y=100) labels[1].place(x=520,y=350) labels[2].place(x=250,y=570) labels[3].place(x=50,y=350) labels[4].place(x=150,y=100) #加载餐桌图像 img_table = Image.open('img/table.png').resize((250,200),Image.BILINEAR) bm_table = ImageTk.PhotoImage(img_table) label_table=Label(root,image=bm_table) label_table.image=bm_table label_table.place(x=240,y=300) #加载叉子类 img_fork = Image.open('img/fork.png').resize((70,130),Image.BILINEAR) bm_fork = ImageTk.PhotoImage(img_fork) label_forks=[] for i in range(5): temp=Label(root,image=bm_fork) label_forks.append(temp) label_forks[0].place(x=320,y=100) label_forks[1].place(x=600,y=150) label_forks[2].place(x=500,y=550) label_forks[3].place(x=150,y=550) label_forks[4].place(x=75,y=175) print('加载完毕') root.mainloop()
大功告成,代码自取,图片自己挑选设计,死锁的解决换种算法,我使用的是简单的”左右手都有叉子才进餐“的算法。关于使用pyinstaller对py文件打包可以参考我的另外一篇文章。喜欢就点个赞再走吧!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2025年04月10日 22时08分40秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
one + two = 3
2021-05-08
sctf_2019_easy_heap
2021-05-09
PyQt5之音乐播放器
2021-05-09
Redis进阶实践之十八 使用管道模式提高Redis查询的速度
2021-05-09
SQL注入
2021-05-09
MPI Maelstrom POJ - 1502 ⭐⭐ 【Dijkstra裸题】
2021-05-09
Problem 330A - Cakeminator (思维)
2021-05-09
LeetCode75 颜色分类 (三路快排C++实现与应用)
2021-05-09
C语言+easyX图形库的推箱子实现
2021-05-09
调试vs2019代码的流程
2021-05-09
脱壳与加壳-加壳-6-代码实现加密导入表
2021-05-09
Typora配置PicGo时,提示Failed to fetch
2021-05-09
bcolz的新操作
2021-05-09
zmq的send
2021-05-09
阿里钉钉面试题
2021-05-09
C++中找资源或者函数的方法
2021-05-09
delete对象时会自动调用类的析构函数
2021-05-09
POD类型
2021-05-09
const与常量,傻傻分不清楚~
2021-05-09
Head First设计模式——迭代器模式
2021-05-09