wxPython的下拉框,没有办法实现多选选项,所以小编想到可以写一个输入框,在点击输入框时,在输入框下方弹出一个有多选列表的窗口
编写这个程序除了wxPython还需安装pynput
pip install pynput
import wx
from pynput import mouse
class CheckComboBox(wx.Panel):
def __init__(self,parent:wx.Frame,size:tuple,choices:list):
"""初始化
Args:
parent (wx.Frame): 父窗口
size (tuple): 大小
choices(list):下拉框列表
"""
#調用父類構造方法
super().__init__(parent,size=size)
#輸入框
self.textCtrl=wx.TextCtrl(self,pos=(0,0),size=size)
listHight=len(choices)*20 if len(choices)<=6 else 120
#浮動窗口
self.listFrame=wx.Frame(self,size=(size[0],listHight),style=wx.FRAME_SHAPED|wx.FRAME_NO_TASKBAR|wx.STAY_ON_TOP)
#複選列表框
self.checkList=wx.CheckListBox(self.listFrame,pos=(0,0),size=(size[0],self.listFrame.GetSize()[1]),choices=choices)
#鼠標監聽器
self.listener = mouse.Listener(on_click=self.OnClick)
self.listener.start()
#綁定複選框選擇事件
self.checkList.Bind(wx.EVT_CHECKLISTBOX, self.OnCheckListBox)
def OnCheckListBox(self,event):
#複選框選擇事件
checked_items = ""
for i in range(self.checkList.GetCount()):
if self.checkList.IsChecked(i):
if checked_items != "":
checked_items+=","
checked_items+=self.checkList.GetString(i)
self.textCtrl.SetValue(checked_items)
def OnClick(self,x,y,button,pressed):
#鼠標點擊事件
if button == mouse.Button.left and pressed:
#輸入框點擊事件
point =self.GetTopLevelParent().ClientToScreen(self.GetPosition())
size=self.textCtrl.GetSize()
if(self.PosInArea((x,y),(point.x,point.y),(point.x+size[0],point.y+size[1]))):
if(self.listFrame.IsShown()):
self.ListFrameHide()
else:
self.ListFrameShow()
return
if button == mouse.Button.left and (pressed and self.listFrame.IsShown()):
#鼠標點擊浮動窗口隱藏
point =self.listFrame.GetPosition()
size=self.listFrame.GetSize()
if(not self.PosInArea((x,y),(point.x,point.y),(point.x+size[0],point.y+size[1]))):
self.ListFrameHide()
def ListFrameShow(self):
"""
顯示浮動窗口
"""
self.listFrame.Show()
point =self.GetTopLevelParent().ClientToScreen(self.GetPosition())
self.listFrame.SetPosition((point.x,point.y+self.GetSize()[1]))
def ListFrameHide(self):
"""
隱藏浮動窗口
"""
self.listFrame.Hide()
def PosInArea(self,point,min,max)->bool:
"""
判斷一個點是否在區域內
Args:
self (_type_): _description_
point (_type_): 點
min (_type_): 區域內最小的點
max (_type_): 區域內最大的點
Returns:
bool: 真為在區域內,假不在區域內
"""
if( min[0]<= point[0] <= max[0] and min[1] <= point[1] <=max[1] ):
return True
else:
return False
if __name__ == "__main__":
app = wx.App(False)
frame = wx.Frame(None)
checkComboBox=CheckComboBox(frame,(100,20),["選項1","選項2","選項3","選項4","選項5","選項6","選項7","選項8","選項9"])
frame.Show(True)
app.MainLoop()