找回密码
 会员注册
查看: 22|回复: 0

Pythontkinter控件全集之组合选择框ttk.ComboBox

[复制链接]

2

主题

0

回帖

7

积分

新手上路

积分
7
发表于 2024-9-5 15:39:13 | 显示全部楼层 |阅读模式
Tkinter标准库Tkinter是Python的标准GUI库,也是最常用的PythonGUI库之一,提供了丰富的组件和功能,包括窗口、按钮、标签、文本框、列表框、滚动条、画布、菜单等,方便开发者进行图形界面的开发。Tkinter库基于TkforUnix/Windows/macOS,由Tcl语言编写。使用Tkinter,可以快速创建桌面应用程序,并支持多平台Windows、macOS、Linux等。tkinter控件全集在python中导入tkinter库后,有18种控件(也称组件):导入方式:importtkinterastkButton、Canvas、Checkbutton、Entry、Frame、Label、LabelFrame、Listbox、Menu、Menubutton、Message、OptionMenu、PanedWindow、Radiobutton、Scale、Scrollbar、Spinbox、Text最学见的按钮、文本框、标签、列表框等都在里边,唯独没看到组合框ComboBox。查过资料后才知道,tkinter库中还有一子模块tkinter.ttk,它包含有包括Combobox在内的20种控件:导入方式:from tkinterimport ttkButton、Checkbutton、Combobox、Entry、Frame、Label、LabelFrame、LabeledScale、Labelframe、Menubutton、Notebook、OptionMenu、PanedWindow、Progressbar、Radiobutton、Scale、Scrollbar、Separator、Sizegrip、Spinbox、Treeview请注意,某些控件在两个模块中都存在(如Button, Checkbutton, Entry等),但它们在外观和行为上可能会有所不同,ttk模块中的控件可以提供更加现代和可定制的外观。以Button为例,都以简单的方式表达,运行后的外观和行为都有些不同。        importtkinterastk         fromtkinterimportttk        button1=tk.Button(root,text="ClickMe",command=button_click)        button2=ttk.Button(root,text="ClickMe",command=button_click)如图所示:完整代码如下:importtkinterastkfromtkinterimportttkdefbutton_click():print("Buttonclicked!")if__name__=='__main__':root=tk.Tk()root.title("Buttonvsttk.Button")root.geometry("400x300")button1=tk.Button(root,text="ClickMe",command=button_click)button1.pack(pady=60)button2=ttk.Button(root,text="ClickMe",command=button_click)button2.pack(pady=20)root.mainloop()以下将介绍今天的主角:ttk.Combobox组合选择框。ComboBox组合选择框ComboBox将几个文本字段组合成为一个可弹出的选择列表。它的原版帮助有3万多字呢,以下挑一些主要的操作方法简单介绍一下:创建并设置选择项  values=["Option1","Option2","Option3","Option4"]  combobox=ttk.Combobox(root,values=values)  combobox.pack()绑定事件ComboboxSelected  combobox.bind("<>",on_select)获取当前选择项combobox.get()combobox.get()以上插图的代码如下:importtkinterastkfromtkinterimportttkdefon_select(event):label.config(text="当前选择为:"+combobox.get())if__name__=='__main__':#创建主窗口root=tk.Tk()root.title("ComboboxExample")root.geometry("400x300")label=tk.Label(root,text="请点击下拉框选择:")label.pack()#创建多选下拉框values=["Option1","Option2","Option3","Option4"]combobox=ttk.Combobox(root,values=values)combobox.pack()combobox.bind("<>",on_select)#运行主循环root.mainloop()设置当前显示项combobox.set()combobox.set()自定义类 SelectCombobox把以上内容综合起来,自定义一个组合框类: importtkinterastkfromtkinterimportttkclassSelectCombobox(ttk.Combobox):def__init__(self,master=None,values=None):super().__init__(master,values=values)self.bind("<>",self.on_select)defon_select(self,event):label.config(text="当前选择为:"+self.get())if__name__=='__main__':#创建主窗口root=tk.Tk()root.title("ComboboxExample")root.geometry("400x300")label=tk.Label(root,text="请点击下拉框选择:")label.pack()#创建多选下拉框values=["Option1","Option2","Option3","Option4"]combobox=SelectCombobox(root,values=values)combobox.pack()#运行主循环root.mainloop()扩展Combobox组合框拓展成多项选择Combobox本身不支持多项选择,变通方法:引入一个列表,用于存放已选项,奇数次选择一个项则存入列表、反之偶数次选择则移除。代码如下:importtkinterastkfromtkinterimportttkclassMultiSelectCombobox(ttk.Combobox):def__init__(self,master=None,values=None,**kwargs):super().__init__(master,values=values,**kwargs)self.bind("<>",self.on_select)self.selected_values=[]defon_select(self,event):selected_value=self.get()#使用get方法获取选中项的值ifselected_valueinself.selected_values:self.selected_values.remove(selected_value)#如果已选中,则移除该选项else:self.selected_values.append(selected_value)#如果未选中,则添加到已选项列表self.selected_values.sort()ifself.selected_values:text='、'.join(self.selected_values)else:text='空'label2.config(text="当前选择为:"+text)if__name__=='__main__':#创建主窗口root=tk.Tk()root.title("Multi-SelectComboboxExample")root.geometry("400x300")label=tk.Label(root,text="请选择:")label.pack()#创建多选下拉框values=["Option1","Option2","Option3","Option4"]combobox=MultiSelectCombobox(root,values=values)combobox.pack()text="当前选择为:空"label2=tk.Label(root,text=text)label2.pack()#运行主循环root.mainloop()选项前添加符号Combobox本身不支持修改选择项,变通方法:在每次变更选项时都重建一个新的组合框,同时把所有的选项前都加上一个全角空格(\u3000),对于已选中的选项,则把前面的全角空格替换成对勾符号(\u2713)。这样子可能更像一个多项选择框,如下图:代码如下:importtkinterastkfromtkinterimportttkdefon_select(event):selected_value=combobox.get()selected_value=selected_value.replace("\u2713","\u3000")ifselected_valueinselected_values:selected_values.remove(selected_value)else:selected_values.append(selected_value)selected_values.sort()ifselected_values:text='、'.join(selected_values).replace('tion','')else:text='空'label.config(text="当前选择为:"+text)update_combobox_options()defupdate_combobox_options():globalcomboboxcombobox.grid_forget()new_values=[]forvinvalues:ifvinselected_values:new_values.append(v.replace("\u3000","\u2713"))else:new_values.append(v)combobox=ttk.Combobox(root,values=new_values,state='readonly')combobox.place(x=100,y=30)combobox.set('请点击选择:')combobox.bind("<>",on_select)if__name__=='__main__':#创建主窗口root=tk.Tk()root.title("Multi-SelectComboboxExample")root.geometry("400x300")#创建多选下拉框values=["Option1","Option2","Option3","Option4"]values=["\u3000"+vforvinvalues]selected_values=[]combobox=ttk.Combobox(root,values=values,state='readonly')combobox.place(x=100,y=30)combobox.set('请点击选择:')combobox.bind("<>",on_select)text="当前选择为:空"label=tk.Label(root,text=text)label.pack(side=tk.BOTTOM)#运行主循环root.mainloop()题外话以上这些是我自己瞎写的变通代码,可能有更好的办法来实现这些功能,也有可能ttk模块本身就有这些功能,只是我没发现而已。另外:如果选择项不至是四个而是有很多,最好能在最前面设置两个选项,全部选择和取消全选,它们不参与进入已选项列表,点击它们只为在其它选项上标注对勾同时填满或清空已选项列表。感兴趣的朋友,可以自己动手实现这两个功能。附件一Combobox英文帮助HelponclassComboboxinmoduletkinter.ttk:classCombobox(Entry) | Combobox(master=None,**kw) |  | TtkComboboxwidgetcombinesatextfieldwithapop-downlistofvalues. |  | Methodresolutionorder: |   Combobox |   Entry |   Widget |   tkinter.Entry |   tkinter.Widget |   tkinter.BaseWidget |   tkinter.Misc |   tkinter.Pack |   tkinter.Place |   tkinter.Grid |   tkinter.XView |   builtins.object |  | Methodsdefinedhere: |  | __init__(self,master=None,**kw) |   ConstructaTtkComboboxwidgetwiththeparentmaster. |    |   STANDARDOPTIONS |    |     class,cursor,style,takefocus |    |   WIDGET-SPECIFICOPTIONS |    |     exportselection,justify,height,postcommand,state, |     textvariable,values,width |  | current(self,newindex=None) |   Ifnewindexissupplied,setsthecomboboxvaluetothe |   elementatpositionnewindexinthelistofvalues.Otherwise, |   returnstheindexofthecurrentvalueinthelistofvalues |   or-1ifthecurrentvaluedoesnotappearinthelist. |  | set(self,value) |   Setsthevalueofthecomboboxtovalue. |  | ---------------------------------------------------------------------- | MethodsinheritedfromEntry: |  | bbox(self,index) |   Returnatupleof(x,y,width,height)whichdescribesthe |   boundingboxofthecharactergivenbyindex. |  | identify(self,x,y) |   Returnsthenameoftheelementatpositionx,y,orthe |   emptystringifthecoordinatesareoutsidethewindow. |  | validate(self) |   Forcerevalidation,independentoftheconditionsspecified |   bythevalidateoption.ReturnsFalseifvalidationfails,True |   ifitsucceeds.Setsorclearstheinvalidstateaccordingly. |  | ---------------------------------------------------------------------- | MethodsinheritedfromWidget: |  | instate(self,statespec,callback=None,*args,**kw) |   Testthewidget'sstate. |    |   Ifcallbackisnotspecified,returnsTrueifthewidgetstate |   matchesstatespecandFalseotherwise.Ifcallbackisspecified, |   thenitwillbeinvokedwith*args,**kwifthewidgetstate |   matchesstatespec.statespecisexpectedtobeasequence. |  | state(self,statespec=None) |   Modifyorinquirewidgetstate. |    |   WidgetstateisreturnedifstatespecisNone,otherwiseitis |   setaccordingtothestatespecflagsandthenanewstatespec |   isreturnedindicatingwhichflagswerechanged.statespecis |   expectedtobeasequence. |  | ---------------------------------------------------------------------- | Methodsinheritedfromtkinter.Entry: |  | delete(self,first,last=None) |   DeletetextfromFIRSTtoLAST(notincluded). |  | get(self) |   Returnthetext. |  | icursor(self,index) |   InsertcursoratINDEX. |  | index(self,index) |   Returnpositionofcursor. |  | insert(self,index,string) |   InsertSTRINGatINDEX. |  | scan_dragto(self,x) |   Adjusttheviewofthecanvasto10timesthe |   differencebetweenXandYandthecoordinatesgivenin |   scan_mark. |  | scan_mark(self,x) |   RememberthecurrentX,Ycoordinates. |  | select_adjust=selection_adjust(self,index) |  | select_clear=selection_clear(self) |  | select_from=selection_from(self,index) |  | select_present=selection_present(self) |  | select_range=selection_range(self,start,end) |  | select_to=selection_to(self,index) |  | selection_adjust(self,index) |   AdjusttheendoftheselectionnearthecursortoINDEX. |  | selection_clear(self) |   Cleartheselectionifitisinthiswidget. |  | selection_from(self,index) |   SetthefixedendofaselectiontoINDEX. |  | selection_present(self) |   ReturnTrueiftherearecharactersselectedintheentry,False |   otherwise. |  | selection_range(self,start,end) |   SettheselectionfromSTARTtoEND(notincluded). |  | selection_to(self,index) |   SetthevariableendofaselectiontoINDEX. |  | ---------------------------------------------------------------------- | Methodsinheritedfromtkinter.BaseWidget: |  | destroy(self) |   Destroythisandalldescendantswidgets. |  | ---------------------------------------------------------------------- | Methodsinheritedfromtkinter.Misc: |  | __getitem__=cget(self,key) |  | __repr__(self) |   Returnrepr(self). |  | __setitem__(self,key,value) |  | __str__(self) |   Returnthewindowpathnameofthiswidget. |  | after(self,ms,func=None,*args) |   Callfunctiononceaftergiventime. |    |   MSspecifiesthetimeinmilliseconds.FUNCgivesthe |   functionwhichshallbecalled.Additionalparameters |   aregivenasparameterstothefunctioncall. Return |   identifiertocancelschedulingwithafter_cancel. |  | after_cancel(self,id) |   CancelschedulingoffunctionidentifiedwithID. |    |   Identifierreturnedbyafterorafter_idlemustbe |   givenasfirstparameter. |  | after_idle(self,func,*args) |   CallFUNConceiftheTclmainloophasnoeventto |   process. |    |   Returnanidentifiertocanceltheschedulingwith |   after_cancel. |  | anchor=grid_anchor(self,anchor=None) |  | bell(self,displayof=0) |   Ringadisplay'sbell. |  | bind(self,sequence=None,func=None,add=None) |   BindtothiswidgetateventSEQUENCEacalltofunctionFUNC. |    |   SEQUENCEisastringofconcatenatedevent |   patterns.Aneventpatternisoftheform |   whereMODIFIERisone |   ofControl,Mod2,M2,Shift,Mod3,M3,Lock,Mod4,M4, |   Button1,B1,Mod5,M5Button2,B2,Meta,M,Button3, |   B3,Alt,Button4,B4,Double,Button5,B5Triple, |   Mod1,M1.TYPEisoneofActivate,Enter,Map, |   ButtonPress,Button,Expose,Motion,ButtonRelease |   FocusIn,MouseWheel,Circulate,FocusOut,Property, |   Colormap,GravityReparent,Configure,KeyPress,Key, |   Unmap,Deactivate,KeyReleaseVisibility,Destroy, |   LeaveandDETAIListhebuttonnumberforButtonPress, |   ButtonReleaseandDETAIListheKeysymforKeyPressand |   KeyRelease.Examplesare |   forpressingControlandmousebutton1or |   <<
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-8 11:35 , Processed in 3.522860 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表