Python tkinter自定义多选下拉列表框

  • 1、demo.py文件
  • 2、ComBoPicker.py文件
  • 3、ComBoPicker1.py文件
  • 4、效果

上一篇文章,很多小伙伴不知道怎么加全选和滚动条,所以做出的修改,增加全选和滚动条,如果有不足之处,欢迎指出,感谢!

问题 方法
怎么动态赋值 COMBOPICKER.values = [1,2,3,4]
获取选中值 1.COMBOPICKER.current_value
2.COMBOPICKER.get()
3.COMBOPICKER.entry_var.get()

1、demo.py文件


from tkinter import *
from ComBoPicker import Combopicker# 导入自定义下拉多选框
from ComBoPicker1 import Combopicker as Combopicker1# 导入自定义下拉多选框
if __name__ == "__main__":root = Tk()root.geometry("300x300")F =Frame(root)F.pack(expand=False, fill="both",padx=10,pady=10)Label(F,text='全选、可滚动:').pack(side='left')COMBOPICKER = Combopicker(F, values = ['全选','项目1','项目2','项目3','项目4','项目5','项目11','项目22','项目33','项目44','项目55'])COMBOPICKER.pack(anchor="w")F2 =Frame(root)F2.pack(expand=False, fill="both",padx=10,pady=10)Label(F2,text='普通:').pack(side='left')COMBOPICKER1 = Combopicker1(F2, values = [f'项目{i}' for i in range(5)])COMBOPICKER1.pack(anchor="w")root.mainloop()

2、ComBoPicker.py文件

'''自定义多选下拉列表
'''
# import tkinter.font as tkFont
import tkinter.ttk as ttk
from tkinter import LabelFrame,IntVar,StringVar,Canvasclass Picker(ttk.Frame):def __init__(self, master=None, activebackground='#b1dcfb', values=[], entry_wid=None, activeforeground='black',selectbackground='#003eff', selectforeground='white', command=None, borderwidth=1, relief="solid"):self._selected_item = Noneself._values = valuesself._entry_wid = entry_widself._sel_bg = selectbackground self._sel_fg = selectforegroundself._act_bg = activebackground self._act_fg = activeforegroundself._command = commandself.index=0ttk.Frame.__init__(self, master, borderwidth=borderwidth,height=10, relief=relief)self.bind("<FocusIn>", lambda event:self.event_generate('<<PickerFocusIn>>'))self.bind("<FocusOut>", lambda event:self.event_generate('<<PickerFocusOut>>'))F = LabelFrame(self)F.pack(fill='x')self.canvas = Canvas(F,scrollregion=(0,0,500,(len(self._values)*21)))vbar = ttk.Scrollbar(F,orient='vertical')vbar.pack(side='right',fill='y')frame = ttk.Frame(self.canvas)vbar.config(command=self.canvas.yview)# self.canvas.pack(side='left',fill='x',expand=True)self.canvas.create_window((0,0,),window=frame,anchor='nw',tags='frame')self.canvas.config(highlightthickness=0)  # 去掉选中边框vbar.config(command=self.canvas.yview)self.canvas.config(width=300,height=150)self.canvas.config(yscrollcommand=vbar.set)# self.canvas.config(scrollregion=self.canvas.bbox('all'))# self._font = tkFont.Font()self.dict_checkbutton = {}self.dict_checkbutton_var = {}self.dict_intvar_item = {}for index,item in enumerate(self._values):self.dict_intvar_item[item] = IntVar()self.dict_checkbutton[item] = ttk.Checkbutton(frame, text = item, variable=self.dict_intvar_item[item],command=lambda ITEM = item:self._command(ITEM))self.dict_checkbutton[item].grid(row=index, column=0, sticky='nsew',padx=5)self.dict_intvar_item[item].set(0)if item in self._entry_wid.get().split(','):self.dict_intvar_item[item].set(1)self.canvas.pack(side='left',expand=True,fill='both')self.canvas.bind("<MouseWheel>",self.processWheel)frame.bind("<MouseWheel>",self.processWheel)for i in self.dict_checkbutton:self.dict_checkbutton[i].bind("<MouseWheel>",self.processWheel)self.bind("<MouseWheel>",self.processWheel)def processWheel(self,event):index = int(-(event.delta))if index > 0:self.canvas.yview_scroll(2,'units')else:self.canvas.yview_scroll(-2, 'units')class Combopicker(ttk.Entry, Picker):def __init__(self, master, values=[], entryvar=None, entrywidth=None, entrystyle=None, onselect=None,activebackground='#b1dcfb', activeforeground='black', selectbackground='#003eff', selectforeground='white', borderwidth=1, relief="solid", state='normal'):self.values=valuesself.master=masterself.activeforeground=activeforegroundself.activebackground=activebackgroundself.selectbackground=selectbackgroundself.selectforeground=selectforegroundif entryvar is not None:self.entry_var = entryvarelse:self.entry_var = StringVar()entry_config = {}if entrywidth is not None:entry_config["width"] = entrywidthif entrystyle is not None:entry_config["style"] = entrystylettk.Entry.__init__(self, master,textvariable=self.entry_var, **entry_config, state=state)self._is_menuoptions_visible = Falseself.picker_frame = Picker(self.winfo_toplevel(), values=values,entry_wid = self.entry_var,activebackground=activebackground, activeforeground=activeforeground, selectbackground=selectbackground, selectforeground=selectforeground, command=self._on_selected_check)self.bind_all("<1>", self._on_click, "+")self.bind("<Escape>", lambda event: self.hide_picker())@propertydef current_value(self):try:value = self.entry_var.get()return valueexcept ValueError:return None@current_value.setterdef current_value(self, INDEX):self.entry_var.set(self.values.index(INDEX))def _on_selected_check(self, SELECTED):value = []all_name = '全选'if self.entry_var.get() != "" and self.entry_var.get() != None:temp_value = self.entry_var.get()value = temp_value.split(",")if str(SELECTED) in value: if all_name == str(SELECTED):value.clear()  # 清空选项else:if all_name in value:value.remove(all_name)value.remove(str(SELECTED))value.sort()else: if all_name == str(SELECTED):value = self.valueselse:value.append(str(SELECTED))value.sort()temp_value = ""for index,item in enumerate(value):if item!= "":if index != 0:temp_value += ","temp_value += str(item)self.entry_var.set(temp_value)# 可以通过复选框的variable来让勾选中或取消,但下面也行,问题不大# 刷新if all_name == str(SELECTED):self.hide_picker()self.show_picker()def _on_click(self, event):str_widget = str(event.widget)if str_widget == str(self):if not self._is_menuoptions_visible:self.show_picker()else:if not str_widget.startswith(str(self.picker_frame)) and self._is_menuoptions_visible:self.hide_picker()def show_picker(self):if not self._is_menuoptions_visible:self.picker_frame = Picker(self.winfo_toplevel(), values=self.values,entry_wid = self.entry_var,activebackground=self.activebackground,activeforeground=self.activeforeground, selectbackground=self.selectbackground, selectforeground=self.selectforeground, command=self._on_selected_check)self.bind_all("<1>", self._on_click, "+")self.bind("<Escape>", lambda event: self.hide_picker())self.picker_frame.lift()self.picker_frame.place(in_=self, relx=0, rely=1, relwidth=1 )self._is_menuoptions_visible = Truedef hide_picker(self):if self._is_menuoptions_visible:self.picker_frame.place_forget() # 不知道为什么这个方式在mac下不起作用,所以就直接销毁这个控件# self.picker_frame.destroy()self._is_menuoptions_visible = False

3、ComBoPicker1.py文件

'''自定义多选下拉列表
'''
import tkinter.font as tkFont
import tkinter.ttk as ttk
from tkinter import *
class Picker(ttk.Frame):def __init__(self, master=None,activebackground='#b1dcfb',values=[],entry_wid=None,activeforeground='black', selectbackground='#003eff', selectforeground='white', command=None, borderwidth=1, relief="solid"):self._selected_item = Noneself._values = valuesself._entry_wid = entry_widself._sel_bg = selectbackground self._sel_fg = selectforegroundself._act_bg = activebackground self._act_fg = activeforegroundself._command = commandttk.Frame.__init__(self, master, borderwidth=borderwidth, relief=relief)self.bind("<FocusIn>", lambda event:self.event_generate('<<PickerFocusIn>>'))self.bind("<FocusOut>", lambda event:self.event_generate('<<PickerFocusOut>>'))self._font = tkFont.Font()self.dict_checkbutton = {}self.dict_checkbutton_var = {}self.dict_intvar_item = {}for index,item in enumerate(self._values):self.dict_intvar_item[item] = IntVar()self.dict_checkbutton[item] = ttk.Checkbutton(self, text = item, variable=self.dict_intvar_item[item],command=lambda ITEM = item:self._command(ITEM))self.dict_checkbutton[item].grid(row=index, column=0, sticky=NSEW)self.dict_intvar_item[item].set(0)class Combopicker(ttk.Entry, Picker):def __init__(self, master, values= [] ,entryvar=None, entrywidth=None, entrystyle=None, onselect=None,activebackground='#b1dcfb', activeforeground='black', selectbackground='#003eff', selectforeground='white', borderwidth=1, relief="solid"):self.values=valuesif entryvar is not None:self.entry_var = entryvarelse:self.entry_var = StringVar()entry_config = {}if entrywidth is not None:entry_config["width"] = entrywidthif entrystyle is not None:entry_config["style"] = entrystylettk.Entry.__init__(self, master, textvariable=self.entry_var, **entry_config, state = "readonly")self._is_menuoptions_visible = Falseself.picker_frame = Picker(self.winfo_toplevel(), values=values,entry_wid = self.entry_var,activebackground=activebackground, activeforeground=activeforeground, selectbackground=selectbackground, selectforeground=selectforeground, command=self._on_selected_check)self.bind_all("<1>", self._on_click, "+")self.bind("<Escape>", lambda event: self.hide_picker())@propertydef current_value(self):try:value = self.entry_var.get()return valueexcept ValueError:return None@current_value.setterdef current_value(self, INDEX):self.entry_var.set(self.values.index(INDEX))def _on_selected_check(self, SELECTED):value = []if self.entry_var.get() != "" and self.entry_var.get() != None:temp_value = self.entry_var.get()value = temp_value.split(",")if str(SELECTED) in value:value.remove(str(SELECTED))else:    value.append(str(SELECTED))value.sort()temp_value = ""for index,item in enumerate(value):if item!= "":if index != 0:temp_value += ","temp_value += str(item)self.entry_var.set(temp_value)def _on_click(self, event):str_widget = str(event.widget)if str_widget == str(self):if not self._is_menuoptions_visible:self.show_picker()else:if not str_widget.startswith(str(self.picker_frame)) and self._is_menuoptions_visible:self.hide_picker()def show_picker(self):if not self._is_menuoptions_visible:self.picker_frame.place(in_=self, relx=0, rely=1, relwidth=1 )self.picker_frame.lift()self._is_menuoptions_visible = Truedef hide_picker(self):if self._is_menuoptions_visible:self.picker_frame.place_forget()self._is_menuoptions_visible = False

4、效果

Python tkinter自定义多选下拉列表框(带滚动条、全选)相关推荐

  1. Python tkinter自定义多选下拉列表框

    Python tkinter 自定义多选下拉列表框 困扰了我好久,终于在stackoverflow上找到了答案. 废话不多说,直接上代码! 加滚动条和全选传送门 :Python tkinter自定义多 ...

  2. JQuery实现复选框CheckBox的全选、反选、提交操作

    对复选框最基本的应用,就是对复选框进行全选.反选和提交等操作.复杂的操作需要与选项挂钩,来达到各种级联反应效果. [示例]使用Jquery实现复选框CheckBox的全选.反选.提交操作. (1)创建 ...

  3. layui checkbox 反选/全选/取消单个取消全选/全部选中勾上全选

    更: 下面连接文章就是解决checkbox只能取到最后一个值的解决办法 https://blog.csdn.net/qq_16513911/article/details/81981733 <d ...

  4. element-ui中el-cascader级联选择器多选判断是否是全选

    给定如多级级联选择器,如果只选中第三级,则展示第三级,如果全选第一级或者第二级则只展示第一级或者第二级.(一级选项如果全部选中的话,只用获取一级选项的值就行了,如果没有全部选中 ,再获取二级选项的值) ...

  5. Python tkinter的text控件加滚动条

    """ 文本控件:用于显示多行文本 """ import tkinterwin = tkinter.Tk() win.title('带滚动条 ...

  6. python怎么全选_python练习题之全选框全不选反选

    功能 实现分为两大部分: 第一body 部分,1,通过 无序列表标签实现选项的基本样式,通过input的checkbox标签实现里面的复选框功能.用到了标签的嵌套.然后选项的js方法含有选中和被选中的 ...

  7. html 复选按钮 全选,JS实现复选按钮控件全选和批量操作

    2.1 准备数据 新建普通报表,新建数据库查询数据集 ds1,SQL 语句为:SELECT * FROM Sales 2.2 设计表格 如下图设计填报模板的表格样式,其中 A3 单元格的左父格为 B3 ...

  8. layui 实现表单、表格中复选框checkbox的全选功能

    一.layui 实现表单中多选框的全选功能,代码如下: //html页面表单 <form class="layui-form"><div class=" ...

  9. element表格取消全选_ElementUi 表格取消全选框,用文字表示

    Echarts ElementUi 表格取消全选框,用文字表示 1.先看看实现的图 一. 添加添加复选框列 二.给 方法(这个方法主要就是给表格所需要的列添加类名.)具体可以看ElementUi的表格 ...

最新文章

  1. flock文件锁的学习和应用
  2. spring-security权限控制详解
  3. django 中使用 channels 实现websocket
  4. 大数据笔记(二十一)——NoSQL数据库之Redis
  5. Arrays.asList的用法
  6. 如何在电脑网页下载准考证
  7. tableau的下载安装及简单使用
  8. Could not mount the media/drive ‘D:\......./VBoxGuestAdditions.iso‘ (VERR_PDM_MEDIA_LOCKED)
  9. 增长黑客,创业公司的用户与收入增长秘籍
  10. 字节扁平化管理上热搜,老板张一鸣群内diss员工划水惨遭回怼!
  11. VUE系列之element表单el-form-item自定义label
  12. marvin java_Java开源图像处理框架Marvin介绍
  13. Could not publish server configuration for Tomcat v8.0 Server at localhost.
  14. 传奇装备元素属性设置教程
  15. [附源码]java毕业设计网上拍卖系统
  16. VOWIFI--相关的协议文档
  17. c语言中编译解释,C语言既可以编译执行又可以解释执行吗? 编译执行怎么解释? 解释执行又怎么解释?...
  18. Python网络爬虫实战12:爬取豆瓣电影中热门电影数据
  19. 新手站长说说之避免网站seo关键词排名的错误做法
  20. P2433 【深基1-2】小学数学 N 合一(题解)​

热门文章

  1. JavaScript之操作符
  2. 荣耀手表显示无法连接服务器,在给苹果手表升级时为何总显示没有连接互联网?...
  3. 机票名字错乘客损失1600元:预订务必核准信息
  4. lesson5-基础IO
  5. python 10个100以内随机整数编辑_Python基础语法合集(转自CSDN)
  6. 基于自适应图学习的不完整多视图谱聚类
  7. 解决Mac下无法识别Android手机的问题
  8. 设备调试之PVLAN技术实践
  9. 如何通过音乐数字化实现创新的音乐数字发行
  10. Java爬虫学习--爬取漫画