UltimateListCtrl 中的小部件 Windows 不会 Resize/Refresh
Widget Windows in UltimateListCtrl Won't Resize/Refresh
我的目标是获得一个 ULC
,其中有一列 TextCtrl
,它会随着用户输入动态调整行的大小,所以如果有更好的方法,请说出来。
这是我试过的方法:
ExpandoTextCtrl
正是我想要的。我有一个有效的例子,所以我知道我能够正确地实施它,我正在寻找这些专栏:
import wx
import sys
import wx.lib.expando as ex
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
text = "\"I\'ll Be Missing You\" is a song recorded by American rapper Puff Daddy and American singer Faith Evans, featuring R&B group 112, in memory of fellow Bad Boy Records artist Christopher \"The Notorious B.I.G.\" Wallace, who was gunned down on March 9, 1997. --Wikipedia"
self.edit_text = ex.ExpandoTextCtrl(self, value = text, size = (200,50))
self.edit_text.SetMaxHeight(sys.maxint)
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="expando Demo")
panel = TestPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()
当您添加或删除行时,它会动态调整任何字符的高度(不仅仅是换行符的数量或类似的简单内容)。
如果我将它添加到 UltimateListCtrl
中的单元格,它的静态大小大约为列宽和 2 行可见文本,因此它甚至不会实例化显示整个文本,但是它也不会调整大小。
我对其他类型的 Window
也有同样的问题是 list
。我写了一个 button
,当你点击它时它会改变它的大小。我的这段代码(如果你愿意,我可以 post 但感觉多余)在它自己的面板中或在 Sizer
与其他小部件等中完美运行,但在 ULC
它只会以原始大小实例化,并且不会随着对 button.SetSize()
.
的调用而改变
我已经研究了 ULC
的错误报告,但没有看到任何相关且未修复的内容。我试过调用 ULC
的 Refresh()
、Update()
和 Show(False/True)
方法,以及父 Panel
和 [=31 上的所有上述方法=] 没有成功。
这是代码,基于 ULC
在线的一个常见示例:
import wx
import sys
from wx.lib.agw import ultimatelistctrl as ULC
import wx.lib.expando as ex
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.sizes = self.size_gen()
font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
boldfont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
boldfont.SetWeight(wx.BOLD)
boldfont.SetPointSize(12)
self.ultimateList = ULC.UltimateListCtrl(self, agwStyle = wx.LC_REPORT
| wx.LC_VRULES
| wx.LC_HRULES
| ULC.ULC_HAS_VARIABLE_ROW_HEIGHT)
info = ULC.UltimateListItem()
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_CHECK
info._image = []
info._format = 0
info._kind = 1
info._text = "Artist Name"
self.ultimateList.InsertColumnInfo(0, info)
info = ULC.UltimateListItem()
info._format = wx.LIST_FORMAT_RIGHT
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_FONT
info._image = []
info._text = "Title"
info._font = boldfont
self.ultimateList.InsertColumnInfo(1, info)
info = ULC.UltimateListItem()
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
info._format = 0
info._text = "Genre"
info._font = font
info._image = []
self.ultimateList.InsertColumnInfo(2, info)
self.ultimateList.InsertStringItem(0, "Newsboys")
self.ultimateList.SetStringItem(0, 1, "Go")
self.ultimateList.SetStringItem(0, 2, "Rock")
text = "\"I\'ll Be Missing You\" is a song recorded by American rapper Puff Daddy and American singer Faith Evans, featuring R&B group 112, in memory of fellow Bad Boy Records artist Christopher \"The Notorious B.I.G.\" Wallace, who was gunned down on March 9, 1997. --Wikipedia"
self.ultimateList.InsertStringItem(1, "Puffy")
edit_text = ex.ExpandoTextCtrl(self.ultimateList, value = text, size=(200,50))
edit_text.SetMaxHeight(sys.maxint)
self.ultimateList.SetItemWindow(1, col=1, wnd=edit_text, expand=True)
self.ultimateList.SetStringItem(1, 2, "Pop")
self.ultimateList.InsertStringItem(2, "Family Force 5")
self.button = wx.Button(self.ultimateList, label='button', size =(200,200))
self.button.Bind(wx.EVT_BUTTON, self.on_button)
self.ultimateList.SetItemWindow(2, 1, self.button, expand=True)
#self.ultimateList.SetStringItem(2, 1, "III")
self.ultimateList.SetStringItem(2, 2, "Crunk")
self.ultimateList.SetColumnWidth(0, 150)
self.ultimateList.SetColumnWidth(1, 200)
self.ultimateList.SetColumnWidth(2, 100)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.ultimateList, 1, wx.EXPAND)
self.SetSizer(sizer)
def on_button(self, event):
self.button.SetSize(self.sizes.next())
def size_gen(self):
sizes = [(150,200),(200,200),(80,80)]
index = 0
while True:
yield sizes[index]
index = index + 1
if index > 2:
index = 0
########################################################################
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="MvP UltimateListCtrl Demo")
panel = TestPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()
编辑
我现在又尝试了几种方法。我摆脱了所有的列格式,并用简单的 list.InsertColumn(index, label)
调用替换了这 3 个块。我所做的最有用的事情是从 ULC.SetItemWindow()
调用中删除 expand=True
。这似乎已将按钮宽度(但不是高度)的控制权返回给按钮。由于它从 150Wx200H 开始,当我调用 next
并且它变为 200x200 时,按钮会溢出到右侧的下一个单元格中。当我再次调用 next
,命令 80x80 尺寸时,按钮缩小到 150x200,无法设置为小于其初始尺寸。
如果我初始化按钮比我需要的小,比如 50x30,那么我可以在两个维度上正确设置所有尺寸 (80,80;200,200),但是按钮然后溢出到右边的邻居中,下面。
您可以看到列表没有刷新任何行。
还可以看到widget保持了原来的左上角位置(也许这是对的,但我不这么认为)
如果我将list.Refresh/DoLayout/Layout/Update
添加到on_button
,它没有任何效果。
拖动或重新定位 window(顶级 Frame
)无效。
ULC.SendSizeEvent
无效。
下一个想法
我还尝试删除整行并插入一个新大小的新按钮,如下所示:
def on_button(self,event):
new_size = self.sizes.next()
print new_size
l = self.ultimateList
label = l.GetItemWindow(1, 1).GetLabel()
l.DeleteItem(1)
self.button = wx.Button(self.ultimateList, label=label, size=new_size)
self.button.Bind(wx.EVT_BUTTON, self.on_button)
l.InsertStringItem(1, 'Family Farce 5')
l.SetItemWindow(1,1,self.button)
l.SetStringItem(1,2,'Crunk')
我不认为这是一个好的策略,因为在每次击键时销毁和重建 edit_text
听起来会有很多问题,但公平地说我还没有尝试过还没有。
无论如何,我可以通过按钮调用它并正确调整大小。问题是 ULC
不会根据新高度甚至初始高度重绘后续行,而是根据行的默认高度重绘。它确实使用正确高度的按钮绘制了重新创建的行。
这次(删除行并添加新行)我注意到调整 window(顶级 Frame
)的大小强制重绘,所以我将 SendSizeEvent
添加到 on_button
现在按钮可以正常工作了。
显然我已经弄明白了如何用新尺寸替换一行。
所以问题仍然是关于 ULC
中的 Window
,我可以动态调整小部件的大小,但是 如何在调整大小后强制 ULC 重绘自己小部件?
另一种说法:为什么 SendSizeEvent
在向列表中插入新项目后强制刷新,而不是在修改现有项目后强制刷新? 我可以将 ULC
子类化并扩展特定方法或 属性 如果我知道要执行哪一个。我试过查看源代码,但我无法弄清它的正反面。
首先:ULC只创建一次线高,如果画线时已经有线高,就不会再做。
此外:当您添加新的 window 时,尺寸会写入线对象。这将永远不会再做,也不能通过任何方式手动触发。
但是:
如果您像这样调整 UltimateListCtrl,它将起作用。
class UltimateListItemData 的函数 GetWindowSize(第 2863 行):
def GetWindowSize(self):
""" Returns the associated window size. """
wnd = self._wnd
if wnd.GetSizer(): # the window is a complex one hold by a sizer
size = wnd.GetBestSize()
else: # simple window, without sizers
size = wnd.GetSize()
print(size)
return size
在您的代码中,您需要使旧行高无效,以便重新计算它:
def on_button(self, event):
self.button.SetSize(self.sizes.next())
self.ultimateList._mainWin.ResetLineDimensions(True)
self.ultimateList._mainWin.RecalculatePositions()
请注意,这会修改 ULC 并访问私有变量。
洛克拉
我的目标是获得一个 ULC
,其中有一列 TextCtrl
,它会随着用户输入动态调整行的大小,所以如果有更好的方法,请说出来。
这是我试过的方法:
ExpandoTextCtrl
正是我想要的。我有一个有效的例子,所以我知道我能够正确地实施它,我正在寻找这些专栏:
import wx
import sys
import wx.lib.expando as ex
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
text = "\"I\'ll Be Missing You\" is a song recorded by American rapper Puff Daddy and American singer Faith Evans, featuring R&B group 112, in memory of fellow Bad Boy Records artist Christopher \"The Notorious B.I.G.\" Wallace, who was gunned down on March 9, 1997. --Wikipedia"
self.edit_text = ex.ExpandoTextCtrl(self, value = text, size = (200,50))
self.edit_text.SetMaxHeight(sys.maxint)
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="expando Demo")
panel = TestPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()
当您添加或删除行时,它会动态调整任何字符的高度(不仅仅是换行符的数量或类似的简单内容)。
如果我将它添加到 UltimateListCtrl
中的单元格,它的静态大小大约为列宽和 2 行可见文本,因此它甚至不会实例化显示整个文本,但是它也不会调整大小。
我对其他类型的 Window
也有同样的问题是 list
。我写了一个 button
,当你点击它时它会改变它的大小。我的这段代码(如果你愿意,我可以 post 但感觉多余)在它自己的面板中或在 Sizer
与其他小部件等中完美运行,但在 ULC
它只会以原始大小实例化,并且不会随着对 button.SetSize()
.
我已经研究了 ULC
的错误报告,但没有看到任何相关且未修复的内容。我试过调用 ULC
的 Refresh()
、Update()
和 Show(False/True)
方法,以及父 Panel
和 [=31 上的所有上述方法=] 没有成功。
这是代码,基于 ULC
在线的一个常见示例:
import wx
import sys
from wx.lib.agw import ultimatelistctrl as ULC
import wx.lib.expando as ex
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.sizes = self.size_gen()
font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
boldfont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
boldfont.SetWeight(wx.BOLD)
boldfont.SetPointSize(12)
self.ultimateList = ULC.UltimateListCtrl(self, agwStyle = wx.LC_REPORT
| wx.LC_VRULES
| wx.LC_HRULES
| ULC.ULC_HAS_VARIABLE_ROW_HEIGHT)
info = ULC.UltimateListItem()
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_CHECK
info._image = []
info._format = 0
info._kind = 1
info._text = "Artist Name"
self.ultimateList.InsertColumnInfo(0, info)
info = ULC.UltimateListItem()
info._format = wx.LIST_FORMAT_RIGHT
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT | ULC.ULC_MASK_FONT
info._image = []
info._text = "Title"
info._font = boldfont
self.ultimateList.InsertColumnInfo(1, info)
info = ULC.UltimateListItem()
info._mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
info._format = 0
info._text = "Genre"
info._font = font
info._image = []
self.ultimateList.InsertColumnInfo(2, info)
self.ultimateList.InsertStringItem(0, "Newsboys")
self.ultimateList.SetStringItem(0, 1, "Go")
self.ultimateList.SetStringItem(0, 2, "Rock")
text = "\"I\'ll Be Missing You\" is a song recorded by American rapper Puff Daddy and American singer Faith Evans, featuring R&B group 112, in memory of fellow Bad Boy Records artist Christopher \"The Notorious B.I.G.\" Wallace, who was gunned down on March 9, 1997. --Wikipedia"
self.ultimateList.InsertStringItem(1, "Puffy")
edit_text = ex.ExpandoTextCtrl(self.ultimateList, value = text, size=(200,50))
edit_text.SetMaxHeight(sys.maxint)
self.ultimateList.SetItemWindow(1, col=1, wnd=edit_text, expand=True)
self.ultimateList.SetStringItem(1, 2, "Pop")
self.ultimateList.InsertStringItem(2, "Family Force 5")
self.button = wx.Button(self.ultimateList, label='button', size =(200,200))
self.button.Bind(wx.EVT_BUTTON, self.on_button)
self.ultimateList.SetItemWindow(2, 1, self.button, expand=True)
#self.ultimateList.SetStringItem(2, 1, "III")
self.ultimateList.SetStringItem(2, 2, "Crunk")
self.ultimateList.SetColumnWidth(0, 150)
self.ultimateList.SetColumnWidth(1, 200)
self.ultimateList.SetColumnWidth(2, 100)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.ultimateList, 1, wx.EXPAND)
self.SetSizer(sizer)
def on_button(self, event):
self.button.SetSize(self.sizes.next())
def size_gen(self):
sizes = [(150,200),(200,200),(80,80)]
index = 0
while True:
yield sizes[index]
index = index + 1
if index > 2:
index = 0
########################################################################
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="MvP UltimateListCtrl Demo")
panel = TestPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = TestFrame()
app.MainLoop()
编辑
我现在又尝试了几种方法。我摆脱了所有的列格式,并用简单的 list.InsertColumn(index, label)
调用替换了这 3 个块。我所做的最有用的事情是从 ULC.SetItemWindow()
调用中删除 expand=True
。这似乎已将按钮宽度(但不是高度)的控制权返回给按钮。由于它从 150Wx200H 开始,当我调用 next
并且它变为 200x200 时,按钮会溢出到右侧的下一个单元格中。当我再次调用 next
,命令 80x80 尺寸时,按钮缩小到 150x200,无法设置为小于其初始尺寸。
如果我初始化按钮比我需要的小,比如 50x30,那么我可以在两个维度上正确设置所有尺寸 (80,80;200,200),但是按钮然后溢出到右边的邻居中,下面。
您可以看到列表没有刷新任何行。 还可以看到widget保持了原来的左上角位置(也许这是对的,但我不这么认为)
如果我将list.Refresh/DoLayout/Layout/Update
添加到on_button
,它没有任何效果。
拖动或重新定位 window(顶级 Frame
)无效。
ULC.SendSizeEvent
无效。
下一个想法 我还尝试删除整行并插入一个新大小的新按钮,如下所示:
def on_button(self,event):
new_size = self.sizes.next()
print new_size
l = self.ultimateList
label = l.GetItemWindow(1, 1).GetLabel()
l.DeleteItem(1)
self.button = wx.Button(self.ultimateList, label=label, size=new_size)
self.button.Bind(wx.EVT_BUTTON, self.on_button)
l.InsertStringItem(1, 'Family Farce 5')
l.SetItemWindow(1,1,self.button)
l.SetStringItem(1,2,'Crunk')
我不认为这是一个好的策略,因为在每次击键时销毁和重建 edit_text
听起来会有很多问题,但公平地说我还没有尝试过还没有。
无论如何,我可以通过按钮调用它并正确调整大小。问题是 ULC
不会根据新高度甚至初始高度重绘后续行,而是根据行的默认高度重绘。它确实使用正确高度的按钮绘制了重新创建的行。
这次(删除行并添加新行)我注意到调整 window(顶级 Frame
)的大小强制重绘,所以我将 SendSizeEvent
添加到 on_button
现在按钮可以正常工作了。
显然我已经弄明白了如何用新尺寸替换一行。
所以问题仍然是关于 ULC
中的 Window
,我可以动态调整小部件的大小,但是 如何在调整大小后强制 ULC 重绘自己小部件?
另一种说法:为什么 SendSizeEvent
在向列表中插入新项目后强制刷新,而不是在修改现有项目后强制刷新? 我可以将 ULC
子类化并扩展特定方法或 属性 如果我知道要执行哪一个。我试过查看源代码,但我无法弄清它的正反面。
首先:ULC只创建一次线高,如果画线时已经有线高,就不会再做。
此外:当您添加新的 window 时,尺寸会写入线对象。这将永远不会再做,也不能通过任何方式手动触发。
但是:
如果您像这样调整 UltimateListCtrl,它将起作用。
class UltimateListItemData 的函数 GetWindowSize(第 2863 行):
def GetWindowSize(self):
""" Returns the associated window size. """
wnd = self._wnd
if wnd.GetSizer(): # the window is a complex one hold by a sizer
size = wnd.GetBestSize()
else: # simple window, without sizers
size = wnd.GetSize()
print(size)
return size
在您的代码中,您需要使旧行高无效,以便重新计算它:
def on_button(self, event):
self.button.SetSize(self.sizes.next())
self.ultimateList._mainWin.ResetLineDimensions(True)
self.ultimateList._mainWin.RecalculatePositions()
请注意,这会修改 ULC 并访问私有变量。
洛克拉