python - wx.ComboCtrl 和 wx.ListCtrl 突出显示背景和大小
问题描述
我正在构建一个附加了 wx.ListCtrl 的 wx.ComboCtrl。这样做的原因是因为我想设置选项的前景色(颜色向用户显示项目的状态)。我希望在下拉框和用户做出选择时显示这些颜色。
我遇到的问题是,在 Linux(Ubuntu 20.04)上,进行选择后,wx.ComboCtrl 的背景颜色保持蓝色(前景色保持白色),即使我将焦点移到另一个小部件。我为要在 ComboCtrl 上显示的文本设置哪种颜色并不重要,它仍然是蓝色背景的白色文本。见截图。
如果我将焦点移到另一个窗口然后回到我自己的窗口,我只能让它显示带有我选择的前景色的默认(灰色)背景。
在 Windows 中不会发生这种情况:选择一个项目后,ComboCtrl 的背景颜色是默认的(灰色),但它确实在选择的周围显示了一条小虚线。见截图。
这是我用来重现问题的修改后的演示代码。代码中的注释是我尝试过的一些事情的遗留物。
#!/usr/bin/env python
import wx
import os
#----------------------------------------------------------------------
#----------------------------------------------------------------------
# This class is used to provide an interface between a ComboCtrl and the
# ListCtrl that is used as the popoup for the combo widget.
class ListCtrlComboPopup(wx.ComboPopup):
def __init__(self):
wx.ComboPopup.__init__(self)
self.lc = None
def AddItem(self, txt, _colour):
self.lc.InsertItem(self.lc.GetItemCount(), txt)
_entry = self.lc.GetItem(self.lc.GetItemCount() - 1)
_entry.SetTextColour(_colour)
#_entry.SetItemTextColour(_colour)
self.lc.SetItem(_entry)
def OnMotion(self, evt):
item, flags = self.lc.HitTest(evt.GetPosition())
if item >= 0:
self.lc.Select(item)
self.curitem = item
def OnLeftDown(self, evt):
self.value = self.curitem
self.Dismiss()
# The following methods are those that are overridable from the
# ComboPopup base class. Most of them are not required, but all
# are shown here for demonstration purposes.
# This is called immediately after construction finishes. You can
# use self.GetCombo if needed to get to the ComboCtrl instance.
def Init(self):
self.value = -1
self.curitem = -1
# Create the popup child control. Return true for success.
def Create(self, parent):
self.lc = wx.ListCtrl(parent, style=wx.LC_SINGLE_SEL | wx.SIMPLE_BORDER | wx.LC_REPORT | wx.LC_NO_HEADER)
self.lc.InsertColumn(0, '')
self.lc.Bind(wx.EVT_MOTION, self.OnMotion)
self.lc.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
return True
# Return the widget that is to be used for the popup
def GetControl(self):
return self.lc
# Called just prior to displaying the popup, you can use it to
# 'select' the current item.
def SetStringValue(self, val):
idx = self.lc.FindItem(-1, val)
if idx != wx.NOT_FOUND:
self.lc.Select(idx)
# Return a string representation of the current item.
def GetStringValue(self):
if self.value >= 0:
return self.lc.GetItemText(self.value)
return ""
# Called immediately after the popup is shown
def OnPopup(self):
wx.ComboPopup.OnPopup(self)
# Called when popup is dismissed
def OnDismiss(self):
print (self.GetStringValue())
wx.ComboPopup.OnDismiss(self)
# This is called to custom paint in the combo control itself
# (ie. not the popup). Default implementation draws value as
# string.
def PaintComboControl(self, dc, rect):
wx.ComboPopup.PaintComboControl(self, dc, rect)
# Receives key events from the parent ComboCtrl. Events not
# handled should be skipped, as usual.
def OnComboKeyEvent(self, event):
wx.ComboPopup.OnComboKeyEvent(self, event)
# Implement if you need to support special action when user
# double-clicks on the parent wxComboCtrl.
def OnComboDoubleClick(self):
wx.ComboPopup.OnComboDoubleClick(self)
# Return final size of popup. Called on every popup, just prior to OnPopup.
# minWidth = preferred minimum width for window
# prefHeight = preferred height. Only applies if > 0,
# maxHeight = max height for window, as limited by screen size
# and should only be rounded down, if necessary.
def GetAdjustedSize(self, minWidth, prefHeight, maxHeight):
return wx.ComboPopup.GetAdjustedSize(self, minWidth, prefHeight, maxHeight)
# Return true if you want delay the call to Create until the popup
# is shown for the first time. It is more efficient, but note that
# it is often more convenient to have the control created
# immediately.
# Default returns false.
def LazyCreate(self):
return wx.ComboPopup.LazyCreate(self)
#----------------------------------------------------------------------
class MyTestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
txt = wx.TextCtrl(self, wx.ID_ANY, pos=(100,100))
comboCtrl = wx.ComboCtrl(self, wx.ID_ANY, "Third item", (10,10), size=(200,-1), style=wx.CB_READONLY)
popupCtrl = ListCtrlComboPopup()
# It is important to call SetPopupControl() as soon as possible
comboCtrl.SetPopupControl(popupCtrl)
# Populate using wx.ListView methods
popupCtrl.AddItem("First Item", [255, 127, 0])
popupCtrl.AddItem("Second Item", [192, 127, 45])
popupCtrl.AddItem("Third Item", [25, 223, 172])
#popupCtrl.GetAdjustedSize(100, 35, 100)
#comboCtrl.SetTextColour(_colour)
comboCtrl.SetForegroundColour(wx.Colour(235, 55, 55))
#----------------------------------------------------------------------
def runTest(frame, nb, log):
win = MyTestPanel(nb, log)
return win
#----------------------------------------------------------------------
overview = """<html><body>
<h2><center>wx.combo.ComboCtrl</center></h2>
A combo control is a generic combobox that allows a totally custom
popup. In addition it has other customization features. For instance,
position and size of the dropdown button can be changed.
</body></html>
"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
问题一:
我怎样才能做到这一点,以便在选择项目后显示适当的文本颜色(我以编程方式设置的颜色)和默认(灰色)背景颜色。
问题2:
下拉 ComboCtrl 时,它显示 ListCtrl,它只有一列。可以看到列表中的“第二项”没有完全显示出来,因为列太窄了。即使 ComboCtrl 调整大小(作为调整父窗口大小的结果),如何使列始终与小部件本身的宽度相同?
问题 3:
不是很重要,但是当我们讨论这个主题时:有没有办法摆脱在 Windows 中运行时显示在所选项目周围的小虚线框?
在此先感谢您对此的想法和想法。
马克。
解决方案
推荐阅读
- kotlin - 我使用 listState 来管理我的 LazColumn 的滚动以显示和隐藏我的标题栏。(分页)
- android - 应用程序运行时如何将数据保存到 sharedPreferences 销毁
- pandas - 如何根据熊猫中的条件提取数据库?
- html - 如何在 HTML 和 CSS 中的标题中的两个元素之间平均间隔一个元素
- django - POST表单提交后django显示消息问题?
- swift - 核心数据:返回对象的通用类函数
- python - Open AI Gym:如何将每个步骤中的多个动作传递到我们的自定义健身房环境?
- laravel - 如何在 laravel 中编写子查询
- python - 在 Python 的内存中不使用额外空间/列表/数组的反向列表
- python - Python的列表不删除的pop和remove方法