【问题标题】:Widget Windows in UltimateListCtrl Won't Resize/RefreshUltimateListCtrl 中的小部件窗口不会调整大小/刷新
【发布时间】:2016-02-25 03:33:36
【问题描述】:

我的目标是得到一个ULC,它有一列TextCtrls,它会随着用户键入而动态调整行的大小,所以如果有更好的方法,请说出来。

这是我尝试过的:

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 行文本可见,因此它甚至不会实例化显示整个文本,但它也不会t 调整大小。

我对其他类型的Windows 有同样的问题是list。我写了一个button,当你点击它时会改变它的大小。我的这段代码(如果你愿意,我可以发布,但感觉多余)在它自己的面板或Sizer 与其他小部件等中完美运行,但在ULC 中它只会以原始大小实例化并且永远不会随着对button.SetSize() 的调用而改变。

我研究了ULC 的错误报告,但没有看到任何相关且未修复的内容。我尝试在父级PanelFrame 上调用ULCRefresh()Update()Show(False/True) 方法,但没有成功。

以下是基于在线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()

编辑

我现在又尝试了几种方法。我摆脱了所有的列格式,并用 simplelist.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,它没有任何效果。

拖动或重新定位窗口(顶层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 不会根据新高度甚至初始高度重绘后续行,而是根据行的默认高度。它确实使用正确高度的按钮绘制了重新创建的行。

这一次(删除行并添加新行)我注意到调整窗口大小(顶层Frame)强制重绘,所以我将SendSizeEvent 添加到on_button,现在按钮可以正常工作了。

显然,我已经想出了如何用新尺寸替换一行。

所以问题仍然是关于ULC 中的Windows,我可以动态调整小部件的大小,但是如何在调整小部件大小后强制 ULC 重新绘制自身? p>

另一种说法:为什么SendSizeEvent在将新项目插入列表后强制刷新,但在修改现有项目后不强制刷新?我可以继承ULC并扩展一个特定的方法或属性,如果我知道该做什么。我已经尝试查看源代码,但我无法确定它的正面或反面。

【问题讨论】:

    标签: python python-2.7 wxwidgets


    【解决方案1】:

    首先:ULC 只创建一次线高,如果在绘制线时该高度已经存在,则不会再次创建。

    此外:当您添加一个新窗口时,大小会被写入 line 对象。这将永远不会再次执行,也不能通过任何方式手动触发。

    但是:

    如果你像这样调整 UltimateListCtrl 它将起作用。

    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 并访问私有变量。

    洛克拉

    【讨论】:

    • 太好了,非常感谢。我可以说我搞砸了类似的东西,但我对 python 和 wx 相对缺乏经验,而且我一直迷失在 11000 行源中。当我回到家时,我会尝试并接受。
    • 它不适合我。我尝试使用您的GetWindowSize 方法对ULC 进行子类化,并替换了您的on_button,如图所示。我认为子类可能有一些奇怪的问题,所以我修改了原来的ultimatelistctrl.py,同样的问题。它就像我第一次编辑中的第二个屏幕截图一样,按钮调整大小但列表不会重绘。如果有帮助,我看不到术语中的打印尺寸(或任何其他输出)。
    • 您是否注意到 ULC 文件中有 2 个 GetWindowSize 函数?在我的版本中,第一个位于 2020,第二个位于 2857。您需要在 2857 进行编辑。它位于 UltimateListItemData 类中
    • 我没有注意到,第一次我只是在 .py 文件中搜索GetWindowSize,但现在我修改了正确的,它工作得很好。我会尝试自己想出一个很好的方法来对它进行子类化,或者让它不那么老套,但与此同时,它与ButtonExpando 一起工作得很好(抓住ex.EVT_ETC_LAYOUT_NEEDED 事件)。干杯!
    猜你喜欢
    • 2014-03-14
    • 2011-05-18
    • 2013-07-10
    • 2011-02-13
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 2018-03-01
    相关资源
    最近更新 更多