如何正确计算wx.TreeCtrl的完全展开宽度
wx.TreeCtrl的首选大小似乎是当树完全折叠时,所有元素都能适应的最小大小。有没有一种好的(也就是跨平台兼容的)方法来计算树在完全展开时的宽度?我现在的解决方案是:
def max_width(self):
dc = wx.ScreenDC()
dc.SetFont(self.GetFont())
widths = []
for item, depth in self.__walk_items():
if item != self.root:
width = dc.GetTextExtent(self.GetItemText(item))[0] + self.GetIndent()*depth
widths.append(width)
return max(widths) + self.GetIndent()
这个方法在win32上效果很好,但在linux上就不行了。有没有办法让TreeCtrl自己告诉我它的大小,这样我就可以覆盖它报告的大小?(总是返回最大展开的宽度)
补充说明:抱歉没有提供我上面使用的函数,但你大概明白我的意思,我是在遍历树,获取每个标签的宽度,并返回最宽的那个的总宽度(考虑了缩进)
2 个回答
0
这段代码在我的Windows和Linux系统上都能正常运行:
def compute_best_size(self):
if os.name == 'nt':
best_size = (self.__max_width_win32(), -1)
else:
best_size = (self.__max_width(), -1)
self.SetMinSize(best_size)
def __max_width_win32(self):
dc = wx.ScreenDC()
dc.SetFont(self.GetFont())
widths = []
for item, depth in self.__walk_items():
if item != self.root:
width = dc.GetTextExtent(self.GetItemText(item))[0] + self.GetIndent()*depth
widths.append(width)
return max(widths) + self.GetIndent()
def __max_width(self):
self.Freeze()
expanded = {}
for item in self.get_items():
if item is not self.root:
expanded[item] = self.IsExpanded(item)
self.ExpandAll()
best_size = self.GetBestSize()
for item in expanded:
if not expanded[item]: self.Collapse(item)
self.Thaw()
return best_size[0]
... 每次往树里添加新项目时,都要调用一下 compute_best_size()
这个函数。
1
我发现 GetBestSize
这个方法似乎会考虑到那些被折叠的项目。例如,在演示中的 wxTreeCtrl
(我用的是Ubuntu和wxPython 2.8.7.1),当我改变内部文本字符串的长度(在我版本的演示中是第74行)时,调用 self.tree.GetBestSize()
返回的值会考虑到这个新的字符串长度,即使这个树状结构没有展开。也许你需要调用一下 SetQuickBestSize(False)
呢?