python tkinter listbox与滚动条的结合体

每次专业课考试总能碰到点奇奇怪怪的题目,就不李姐,非常不李姐,现在的题目就喜欢把各种各样的奇奇怪怪东西混合到一起,哎~头大

先瞅眼题目

 第一眼看到这个题目就跟非常炸裂啊,竟然有滚动条!!!

它的布局也好奇怪,啊,光看到这里,心态就已经快炸了,更何况还有个滚动条

 哎,该来的还是得来,咋办,整呗~直接掏他不犯毛病嗷

思考一下布局,这种奇奇怪怪的布局用place()不怎么现实,还得自己慢慢找位置,况且考试也没那么多时间,grid()也不大可能,所以,只剩下一种了,就是pack()布局

布局实现

看布局,直接无脑side='top',最后一行的时候再left来right去的,咱仔细想想,其中有个很奇怪的地方,它的滚动条跟listbox靠的很近,感觉好像就在里面一样,但是,用过的大佬都知道,这个东西不是在外面的嘛,他是怎么混到里面去的

这时候可能有大佬就想到框架了,咱来试试,开头不多说,还是老一套

from tkinter import *
w=Tk()
w.title('请写出你想去的景点/区(可多选)') #窗口标题
w.geometry('345x300')# 窗口大小,我觉得这个大小跟原题目大小差不多

其次,咱先创建两个框架,随便取个名字

fa=Frame(w) #第一个框架用于将列表框和滚动条结合在一起
fa.pack()
fb=Frame(w) #就是下面的单行文本框和两个按钮
fb.pack()
'''
注意,实际写代码时需要将以上代码写在需要的位置,不然会位置错乱
'''

我个人习惯,接下来就直接写函数了,可能大佬的习惯不一样(轻点喷)

def f1():
    pass #为啥写pass捏,先占着位置,看看布局有没有啥问题,布局没问题了再来想想函数咋写
def f2():
    pass

再就是控件(Label,Entry,Button)咱先把会写的写了,难的留到最后慢慢啃

'''
标签
'''
Label(w,text='请写出你想去的景点/区(可多选)').pack()
'''
单行文本框和按钮
这里就得套框架了,不然实现不了
'''
e1=Entry(fa);e1.pack(side='left')
Button(fa,text='添加',command=f1).pack(side='left')
Button(fa,text='删除',command=f2).pack(side='left')

列表框的代码不难,但是加了Scrollbar之后就难了,先看看实现列表框的代码

from tkinter import *
w=Tk()
w.title('请写出你想去的景点(可多选)')
w.geometry('350x300')
def f1():
    pass
def f2():
    pass
Label(w,text='请写出你想去的景点/区(可多选)').pack()
fa=Frame(w)
fa.pack()
l1=Listbox(fa,width=30)
l1.pack()
ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']
for i in ls:
    l1.insert('end',i)
fb=Frame(w)
fb.pack()
e1=Entry(fb);e1.pack(side='left')
Button(fb,text='添加',command=f1).pack(side='left')
Button(fb,text='删除',command=f2).pack(side='left')
w.mainloop()

这时候就会发现框里面啥都没有,空空如也,看看题目中的列表框,里面有数据,所以,这是一开始就有的

怎么在开始的时候就往里面加数据捏,只有一个方法,那就是insert() 添加,但是题目里面的数据那么老长一串,咋办捏,整个列表循环呗

所以,代码可以这么写

'''
先创建一个列表,将所有需要的东西全放进去
然后通过循环的方法将ls列表里面的元素添加到listbox里面
'''
ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']
for i in ls:
    l1.insert('end',i)

所以,关于listbox 的整体代码就写完啦

ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']
l1=Listbox(fb)
l1.pack()
for i in ls:
    l1.insert(0.0,i)

OK!咱把整体代码整合一下,看看运行效果

from tkinter import *
w=Tk()
w.title('请写出你想去的景点(可多选)')
w.geometry('350x300')
def f1():
    pass
def f2():
    pass
Label(w,text='请写出你想去的景点/区(可多选)').pack()
fa=Frame(w)
fa.pack()
l1=Listbox(fa,width=30)
l1.pack()
ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']
for i in ls:
    l1.insert('end',i)
fb=Frame(w)
fb.pack()
e1=Entry(fb);e1.pack(side='left')
Button(fb,text='添加',command=f1).pack(side='left')
Button(fb,text='删除',command=f2).pack(side='left')
w.mainloop()

运行效果,瞅着还行

既然框架实现了,接下来就该实现滚动条和列表框绑定在一起

 实现列表框与滚动条的结合

之前咱不是写了个框架嘛,所以再绑定这一块应该不难,主要是滚动条的各种属性,想想都头大

 既然如此咱就来复习复习滚动条Scrollbar有哪些让人头大的东西

下面是属性

名称说明
background(bg)指定背景颜色,默认值由系统指定
command当滚动条更新时回调的函数,通常指定对应组件的 xview() 或 yview() 方法
orient

指定绘制 “horizontal”(垂直滚动条)还是 “vertical”(水平滚动条)

默认值是 VERTICAL

注意:使用horiaontal属性时,一定记住垂直不是整个条垂直,而是里面的滑块

与x轴垂直,与y轴平行(易错点,要牢记)

width指定滚动条的宽度,默认值是 16px

下面是方法

名称说明
get()返回当前滑块的位置 (a, b),其中 a 值表示当前滑块的顶端或左端的位置,b 值表示当前滑块的底端或右端的位置。
set()

1. 设置当前滚动条的位置

2. 该方法有两个参数即 (first, last),其中 first 表示当前滑块的顶端或左端的位置,last 表示当前滑块的底端或右端的位置(范围 0.0 ~ 1.0)

关于属性为啥就写4个,方法就俩,主要原因还是它的属性名难记(都是老长的),而且并不是很常用,况且咱考试也就考这几个,记那老多的没啥用,还容易搞混,真记不住,哎

重新熟悉了以后,咱再开始写滚动条

s=Scrollbar(fa) #fa为框架名称
s.pack(side='right',fill=Y)
'''
省略代码
'''
s.config(command=l1.yview)#非常重要,必不可少

欸?不是垂直的嘛?为啥没有orient='horizontal'这个属性

因为默认就是垂直方向的,当时发现这个问题的时候都快给我CUP干烧了

使用horiaontal属性时,一定记住垂直不是整个条垂直,而是里面的滑块

与x轴垂直,与y轴平行

所以我觉得,horizontal应该叫水平滚动条,vertical才是垂直滚动条(仅代表个人意见)

OK,加进代码中,看看最后的运行效果

代码如下

from tkinter import *
w=Tk()
w.title('请写出你想去的景点(可多选)')
w.geometry('350x300')
def f1():
    pass
def f2():
    pass
Label(w,text='请写出你想去的景点/区(可多选)').pack()
fa=Frame(w)
fa.pack()
s=Scrollbar(fa)
s.pack(side='right',fill=Y)
l1=Listbox(fa,width=30)
l1.pack()
ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']
for i in ls:
    l1.insert('end',i)
fb=Frame(w)
fb.pack()
e1=Entry(fb);e1.pack(side='left')
Button(fb,text='添加',command=f1).pack(side='left')
Button(fb,text='删除',command=f2).pack(side='left')
w.mainloop()

运行效果

效果瞅着还行,然后就是解决函数部分

 函数实现

在前面我们已经写好了f1和f2函数,用来实现添加和删除

添加应该不是很难,所以代码可以这么写

def f1():
    a=e1.get()#给变量名a赋从e1获取的值
    l1.insert('end',a)#在末尾添加

删除应该也很简单,所以代码也可以这么写

def f2():
    l1.delete('active')#active就是当前选中的值

所以,整体的完整代码应该是这样的

from tkinter import *
w=Tk()
w.title('请写出你想去的景点(可多选)')
w.geometry('350x300')
def f1():
    a=e1.get()
    l1.insert('end',a)
def f2():
    l1.delete('active')
Label(w,text='请写出你想去的景点/区(可多选)').pack()
fa=Frame(w)
fa.pack()
s=Scrollbar(fa)
s.pack(side='right',fill=Y)
l1=Listbox(fa,width=30)
l1.pack()
ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']
for i in ls:
    l1.insert('end',i)
fb=Frame(w)
fb.pack()
e1=Entry(fb);e1.pack(side='left')
Button(fb,text='添加',command=f1).pack(side='left')
Button(fb,text='删除',command=f2).pack(side='left')
w.mainloop()

但是,事情真的会这么简单吗?

 再去从头看一遍题目就会发现,竟然要多选!!!!!!

我……

可恶啊,我竟然没有发现,这眼睛,不要也罢!!!!!

实现Litsbox列表框的多选

哎,发现了咱就解决呗!也不是很难,只需要再源代码上加一点点的改动

这里就需要用到curselection()方法获取选中元素的索引列表,然后循环删除这些元素

同时再写列表框时要加上selectmode='multiple',这样才能实现多选

代码如下:

def f2():
    a1=l1.curselection()#获取选定元素的下标,然后循环删除
    for i in a1:
        l1.delete(i)
'''
代码省略
'''
l1=Listbox(fa,width=30,selectmode='multiple')#将selectmode属性设定为multiple,这样就能多选

 所以,最后的答案应该是这样的

from tkinter import *
w=Tk()
w.title('请写出你想去的景点(可多选)')
w.geometry('350x300')
def f1():
    a=e1.get()
    l1.insert('end',a)
def f2():
    a1=l1.curselection()
    for i in a1:
        l1.delete(i)
Label(w,text='请写出你想去的景点/区(可多选)').pack()
fa=Frame(w)
fa.pack()
s=Scrollbar(fa)
s.pack(side='right',fill=Y)
l1=Listbox(fa,width=30,selectmode='multiple')
l1.pack()
ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']
for i in ls:
    l1.insert('end',i)
fb=Frame(w)
fb.pack()
e1=Entry(fb);e1.pack(side='left')
Button(fb,text='添加',command=f1).pack(side='left')
Button(fb,text='删除',command=f2).pack(side='left')
w.mainloop()

 运行效果就请各位大佬自行复制代码运行,因为实在懒得做动图

好啦!这篇文章到这里就结束啦!

我是梦璃,一个正在被python制裁的高三社畜

修改(24/4/12)

今天做到另一个类型的题目,也是跟这个差不多,不过变成了Text绑定Scrollbar,在这个滚动问题上思考了很久,突然发现那时候写的这篇 文章有bug,就是在数据变多的时候,滚动条一点作用都没有,待我浅浅修改一下……

主要问题就是绑定问题,只需要添加一点代码就足够啦!

'''
其余代码省略,只展现关键代码
'''
s=Scrollbar(fa,command=l1.yview)
#以上代码主要作用为将滚动条与列表框绑定,其中yview为垂直方向,xview为水平方向

l1.configure(yscrollcommand=s.set)
#以上代码同样为滚动条与列表框绑定

s.pack(side='right',fill=Y)
#设置滚动体的位置,以及填充方向

注意:如果想让滚动条产生作用,列表框内的数据得够多,不然也没用

如果按照题目的数据,这样写的话滚动条是用不了的

因为数据就那点,刚好完全显示,这时候绑定一点用没有

其实,这题改不改无所谓,改的话还就得加数据,觉得没必要

加完数据的代码长这样

from tkinter import *
w=Tk()
w.title('请写出你想去的景点(可多选)')
w.geometry('350x300')
def f1():
    a=e1.get()
    l1.insert('end',a)
def f2():
    a1=l1.curselection()
    for i in a1:
        l1.delete(i)
Label(w,text='请写出你想去的景点/区(可多选)').pack()
fa=Frame(w)
fa.pack()

l1=Listbox(fa,width=30,selectmode='multiple')

ls=['杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村',
    '杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村',
    '杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村',
    '杭州西湖', '黄山', '九华山', '九寨沟', '故宫', '八达岭','大雁塔', '天涯海角', '苏州园林', '西递宏村']

for i in ls:
    l1.insert('end',i)
    
s=Scrollbar(fa,command=l1.yview)
l1.configure(yscrollcommand=s.set)
s.pack(side='right',fill=Y)
l1.pack()

fb=Frame(w)
fb.pack()
e1=Entry(fb);e1.pack(side='left')
Button(fb,text='添加',command=f1).pack(side='left')
Button(fb,text='删除',command=f2).pack(side='left')
w.mainloop()

哎,累了,从下午改代码改到凌晨,睡觉睡觉,晚安各位~

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值