关于如何使得Tkinter中在画布上的图片随画布的变化而变化
主要问题:1.在画布上导入的图片无法全覆盖画布
2.图片不随画布的缩放而缩放或者随窗口的缩放而缩放
PS:另外希望有大佬跟我讲解一下具体什么时候才使用全局变量
本人Python新手一枚,在网上查阅相关资料后无果,特发此贴请求各路大佬的指点{:10_298:}
在此鸣谢提供代码的@qq1151985918大佬,基于此代码我稍作改动,代码贴在下方,希望能基于此代码提供相关修改代码
from os import listdir
from tkinter import *
from tkinter import filedialog
from PIL import Image,ImageTk
files = {}
img_open = None
img = None
help_text="""
1.打开文件
2.选择打开文件或文件夹
3.单击显示图片
"""
root = Tk()
root.title("树叶计数")
root.geometry("600x600")
#-------------------命令----------------------#
def open_file():
file_paths = filedialog.askopenfilenames()
list1.delete(0,END)
files.clear()
file_list = []
for file_path in file_paths:
name = file_path.split("/")[-1]
file_list.append(name)
files = file_path
list1.insert(END,name)
def open_dir():
dir_path = filedialog.askdirectory()
list1.delete(0,END)
files.clear()
file_names = []
target_file_name = ["jpg","png","gif"]
for name in listdir(dir_path):
if name.split(".")[-1].lower() in target_file_name:
file_names.append(name)
files = dir_path+"/"+name
list1.insert(END,name)
def show_view(event):
global img_open
global img
get_file = list1.get(ACTIVE)
file_path = files
img_open = Image.open(file_path)
img_open.thumbnail((400,600),Image.ANTIALIAS)
img = ImageTk.PhotoImage(img_open)
back.create_image(200,300,anchor=CENTER,image=img)
#-------------------菜单栏--------------------#
menubar = Menu(root)
file_menu = Menu(menubar,tearoff=0)
file_menu.add_command(label="打开文件",command=open_file)
file_menu.add_command(label="打开文件夹",command=open_dir)
file_menu.add_separator()
file_menu.add_command(label="退出",command=root.quit)
menubar.add_cascade(label="文件",menu=file_menu)
train_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="训练",menu=train_menu)
test_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="测试",menu=test_menu)
detect_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="检测",menu=detect_menu)
root.config(menu=menubar)
#------------------画布-----------------------#
back = Canvas(root,width=400,height=600,bg="white")
back.pack(side=RIGHT,fill=BOTH,expand=True)
back.create_text(200,300,anchor=CENTER,text=help_text)
#------------------滚动条---------------------#
sb = Scrollbar(root)
sb.pack(side=RIGHT,anchor=CENTER,fill=Y)
#-------------------列表框--------------------#
list1 = Listbox(root,yscrollcommand=sb.set)
list1.pack(side=LEFT,fill=Y)
list1.bind("<Button-1>",show_view)
sb.config(command=list1.yview())
root.mainloop() 全局变量 你要看你需要这个变量的场景,如果只是函数需要这个变量,其他的地方都没用到,那么他就不用作为全局,全局之所以全局 也是因为其他的函数需要使用到他,那么必然是经常性的引用,所以就需要这个全局了,必然不可能每次局部定义一个在返回在更改把,这样多麻烦。全局就是统筹了大家使用的东西的一致性,节省了变量额外多使用和程序中的一些设定会方便点。 tkinter Treeview 在线观看妹子图组件自适应窗口 多线程 太过暴力请谨慎使用
https://fishc.com.cn/thread-201655-1-1.html
(出处: 鱼C论坛)
我昨晚突发奇想没事干写的
就是我给你发的代码的基础上敲的
仔细看看,应该有你想要的。
另外给你的这个代码,就你帖子中这个,我其实后来有修改
就是删除了 30334246 行,当时只是随手就敲了,直觉会有用
后来发现没用到,就删掉了,你原帖现在看到的就是我删除后的
看得出来,代码有所修改,应该是你自己手动敲了一遍
给楼主一些小小的建议
写代码最好从开始养成比较良好的习惯,这样代码才会美观,有可读性
即使不注释也能看得清楚明白,自己将来即使过了一段时间也能看得懂
包括别人也看得懂
我看到代码中其实并没什么变化,加了几行注释,布局方式有所改变
改了几个变量和常量,这都是好事
我的习惯不一定适合楼主你自己
有自己的方法习惯最好不过
不过我发现代码中少了几乎所有的间隔空格
如果是楼主自己敲了一遍,那真是再好不过
希望楼主能够有所进步
也希望楼主能在写代码的时候多注意这些小细节
养成良好的习惯
如果是特地删除,那么大可不必
我原来发给楼主的是比较规范的普遍的约定俗成的代码
而特地把空格删除并不能给代码带来什么好处
既不会减少内存也不会加快运行速度
反而会显得密集凌乱,使代码的可读性有所降低
最后建议楼主仔细看看我上面的链接,说不定你想要的答案就找到了{:9_227:} gdmao002 发表于 2021-8-31 16:49
全局变量 你要看你需要这个变量的场景,如果只是函数需要这个变量,其他的地方都没用到,那么他就不用作为 ...
{:5_110:} qq1151985918 发表于 2021-8-31 17:20
tkinter Treeview 在线观看妹子图组件自适应窗口 多线程 太过暴力请谨慎使用
https://fishc.com.cn/thre ...
正在研究你的那个代码{:7_146:},十分感谢 qq1151985918 发表于 2021-8-31 17:20
tkinter Treeview 在线观看妹子图组件自适应窗口 多线程 太过暴力请谨慎使用
https://fishc.com.cn/thre ...
缩放的部分在定义show_img和refresh那吧。我想详细请教一下这个,还有就是我用的是pack()实现的,我想能不能基于pack()来完成这项工作。
PS:我自己只是修改了一些细节,像是布局什么的,我想基于我的布局来完成这个 黎明丿晓小 发表于 2021-8-31 18:07
缩放的部分在定义show_img和refresh那吧。我想详细请教一下这个,还有就是我用的是pack()实现的,我想能 ...
当然可以,了解一下config这个方法吧。 qq1151985918 发表于 2021-8-31 20:12
当然可以,了解一下config这个方法吧。
恕我直言,那个代码我把能想到的地方都改着试了试,还是不行,需要你指点一下{:10_285:} 黎明丿晓小 发表于 2021-8-31 20:49
恕我直言,那个代码我把能想到的地方都改着试了试,还是不行,需要你指点一下
把你改了之后的代码发一下 qq1151985918 发表于 2021-8-31 21:13
把你改了之后的代码发一下
我把你的一些尺寸数据套用了,我不会判断组件究竟怎么放置到自己想要的位置{:10_269:} ,这个假期刚起步,很多东西都还是一片空白,先是照着别人的学习
from os import listdir
from tkinter import *
from tkinter import filedialog
from PIL import Image,ImageTk
files = {}
img_open = None
img = None
help_text="""
1.打开文件
2.选择打开文件或文件夹
3.单击显示图片
"""
#-------------------命令----------------------#
def open_file():
file_paths = filedialog.askopenfilenames()
list1.delete(0,END)
files.clear()
file_list = []
for file_path in file_paths:
name = file_path.split("/")[-1]
file_list.append(name)
files = file_path
list1.insert(END,name)
def open_dir():
dir_path = filedialog.askdirectory()
list1.delete(0,END)
files.clear()
file_names = []
target_file_name = ["jpg","png","gif"]
for name in listdir(dir_path):
if name.split(".")[-1].lower() in target_file_name:
file_names.append(name)
files = dir_path+"/"+name
list1.insert(END,name)
def show_view(event):
global img_open
global img
get_file = list1.get(ACTIVE)
file_path = files
canvas_width = back.winfo_width()
canvas_height = back.winfo_height()
img_open = Image.open(file_path)
img_open.thumbnail((canvas_width,canvas_height),Image.ANTIALIAS)
img = ImageTk.PhotoImage(img_open)
back.create_image(canvas_width / 2, canvas_height / 2,anchor=CENTER,image=img)
def refresh(event):
root_width = root.winfo_width()
root_height = root.winfo_height()
sb.place(x=205, y=5, width=15, height=root_height - 10)
back.place(x=225, y=5, width=root_width - 230, height=root_height - 10)
root = Tk()
root.title("树叶计数")
root.geometry("500x400")
root.bind("<Configure>",refresh)
#-------------------菜单栏--------------------#
menubar = Menu(root)
file_menu = Menu(menubar,tearoff=0)
file_menu.add_command(label="打开文件",command=open_file)
file_menu.add_command(label="打开文件夹",command=open_dir)
file_menu.add_separator()
file_menu.add_command(label="退出",command=root.quit)
menubar.add_cascade(label="文件",menu=file_menu)
train_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="训练",menu=train_menu)
test_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="测试",menu=test_menu)
detect_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="检测",menu=detect_menu)
root.config(menu=menubar)
#------------------画布-----------------------#
back = Canvas(root,width=400,height=600,bg="white")
back.place(x=225, y=5, width=270, height=390)
#back.pack(side=RIGHT,fill=BOTH,expand=True)
back.create_text(200,300,anchor=CENTER,text=help_text)
#------------------滚动条---------------------#
sb = Scrollbar(root)
sb.place(x=205, y=5, width=15, height=390)
#sb.pack(side=RIGHT,anchor=CENTER,fill=Y)
#-------------------列表框--------------------#
list1 = Listbox(root,yscrollcommand=sb.set)
list1.pack(side=LEFT,fill=Y)
list1.bind("<Button-1>",show_view)
sb.config(command=list1.yview())
root.mainloop() 黎明丿晓小 发表于 2021-8-31 21:35
我把你的一些尺寸数据套用了,我不会判断组件究竟怎么放置到自己想要的位置 ,这个假期刚起步 ...
from os import listdir
from tkinter import *
from tkinter import filedialog
from PIL import Image,ImageTk
files = {}
img_open = None
img = None
help_text="""
1.打开文件
2.选择打开文件或文件夹
3.单击显示图片
"""
root = Tk()
root.title("树叶计数")
root.geometry("600x600")
# -------------------命令----------------------#
def open_file():
file_paths = filedialog.askopenfilenames()
list1.delete(0,END)
files.clear()
file_list = []
for file_path in file_paths:
name = file_path.split("/")[-1]
file_list.append(name)
files = file_path
list1.insert(END,name)
def open_dir():
dir_path = filedialog.askdirectory()
list1.delete(0,END)
files.clear()
file_names = []
target_file_name = ["jpg","png","gif"]
for name in listdir(dir_path):
if name.split(".")[-1].lower() in target_file_name:
file_names.append(name)
files = dir_path+"/"+name
list1.insert(END,name)
def show_view(event):
global img_open
global img
try:
back.delete("all") # 清空原画布所有内容
get_file = list1.get(ACTIVE)
file_path = files
except:
return
back_width = back.winfo_width() # 获取当前画布宽度
back_height = back.winfo_height() # 获取当前画布高度
img_open = Image.open(file_path)
img_open.thumbnail((back_width,back_height),Image.ANTIALIAS) # 以当前画布尺寸适应大小
img = ImageTk.PhotoImage(img_open)
back.create_image(back_width/2,back_height/2,anchor=CENTER,image=img) # 重新定义画布中心
def refresh(event):
root_width = root.winfo_width() # 获取当前窗口尺寸
root_height = root.winfo_height()
back.config(width=root_width-200, height=root_height-10) # 重新设置画布尺寸
show_view(1) # 重新显示当前图片 参数 1 必须但不唯一,可以是任何内容
# 这里的参数 event 有必要解释一下,event 是事件,
# 一般来说是tkinter当前控件的某种属性
# 当使用bind方法绑定一个方法时必须指定的一个参数,但不一定要用到
# 等你用多了就了解了
# -------------------菜单栏--------------------#
menubar = Menu(root)
file_menu = Menu(menubar,tearoff=0)
file_menu.add_command(label="打开文件",command=open_file)
file_menu.add_command(label="打开文件夹",command=open_dir)
file_menu.add_separator()
file_menu.add_command(label="退出",command=root.quit)
menubar.add_cascade(label="文件",menu=file_menu)
train_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="训练",menu=train_menu)
test_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="测试",menu=test_menu)
detect_menu = Menu(menubar,tearoff=0)
menubar.add_cascade(label="检测",menu=detect_menu)
root.config(menu=menubar)
# ------------------画布-----------------------#
back = Canvas(root,width=400,height=600,bg="white")
back.pack(side=RIGHT,fill=BOTH,expand=True)
back.create_text(200,300,anchor=CENTER,text=help_text)
# ------------------滚动条---------------------#
sb = Scrollbar(root)
sb.pack(side=RIGHT,anchor=CENTER,fill=Y)
# -------------------列表框--------------------#
list1 = Listbox(root,yscrollcommand=sb.set)
list1.pack(side=LEFT,fill=Y)
list1.bind("<Button-1>",show_view)
sb.config(command=list1.yview())
root.bind("<Configure>",refresh) # 绑定refersh函数为窗口属性变化事件
root.mainloop()
看代码不能只知其一不知其二,联系上下来看就容易理解得多
你回复中的代码太乱了我没用
用的是你帖子中的代码
对照一下吧,我给你加了注释 qq1151985918 发表于 2021-8-31 22:36
看代码不能只知其一不知其二,联系上下来看就容易理解得多
你回复中的代码太乱了我没用
用的是你 ...
好的,感谢{:10_254:} qq1151985918 发表于 2021-8-31 22:36
看代码不能只知其一不知其二,联系上下来看就容易理解得多
你回复中的代码太乱了我没用
用的是你 ...
学习的路上任重而道远,修改后的代码又有新东西值得我去探讨和学习{:5_109:} {:5_95:} 。 {:10_269:} qq1151985918 发表于 2021-8-31 22:36
看代码不能只知其一不知其二,联系上下来看就容易理解得多
你回复中的代码太乱了我没用
用的是你 ...
你好呀~是这样的,我这样理解你看对不对
def show_view(event):
global img_open
global img
try:
back.delete("all")
get_file = list1.get(ACTIVE)
file_path = files
except:
return
back_width = back.winfo_width()
back_height = back.winfo_height()
img_open = Image.open(file_path)
img_open.thumbnail((back_width, back_height), Image.ANTIALIAS)
img = ImageTk.PhotoImage(img_open)
back.create_image(back_width / 2, back_height / 2, anchor=CENTER, image=img)
def refresh(event):
root_width = root.winfo_width()
root_height = root.winfo_height()
back.config(width=root_width - 200, height=root_height - 10)
show_view(1)
当窗口尺寸发生变化时调用refresh函数,然后refresh下的show_view(1)中的值为1表示调用show_view()函数下的try模块;否则窗口不变化就调用except中的return,返回一个空值,这个直接return直接接空我不是太理解。我之前尝试着把异常处理try,except去掉,直接输入代码,如下:
def show_view(event):
global img_open
global img
back.delete(ALL)
get_file = list1.get(ACTIVE)
file_path = files
back_width = back.winfo_width()
back_height = back.winfo_height()
img_open = Image.open(file_path)
img_open.thumbnail((back_width,back_height),Image.ANTIALIAS)
img = ImageTk.PhotoImage(img_open)
back.create_image(back_width / 2, back_height / 2,anchor=CENTER,image=img)
结果返回错误,如图,希望能够得到指点 我好像懂了,刚才又重新试了遍,如果没有try,except异常处理,可以正常运行,但就是一直报错,你这么做是为了把报错消除掉吧,只要一报错就运行except返回一个空值,他就不会报错了{:10_298:} 楼主千金散尽还复来 挣鱼币做作业
页:
[1]
2