Python UltimateListCtrl中的小部件窗口赢得';t调整大小/刷新

Python UltimateListCtrl中的小部件窗口赢得';t调整大小/刷新,python,python-2.7,wxwidgets,Python,Python 2.7,Wxwidgets,我的目标是得到一个ULC,它有一列TextCtrls,可以根据用户的输入动态调整行的大小,所以如果有更好的方法,就这么说 以下是我尝试过的: ExpandoTextCtrl正是我想要的。我有一个工作示例,因此我知道我能够正确地实现它,我正在寻找以下一列: import wx import sys import wx.lib.expando as ex class TestPanel(wx.Panel): def __init__(self, parent): wx.Pa

我的目标是得到一个
ULC
,它有一列
TextCtrl
s,可以根据用户的输入动态调整行的大小,所以如果有更好的方法,就这么说

以下是我尝试过的:

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
中的单元格中,它的静态大小大约为列宽,两行文本可见,因此它甚至不会实例化显示整个文本,但也不会调整大小

对于其他类型的
窗口
s,我也有同样的问题,那就是
列表
。我写了一个
按钮
,当你点击它时,它会改变大小。我的这段代码(如果你愿意,我可以发布,但它感觉多余)可以在自己的面板中运行,也可以在带有其他小部件的
Sizer
中运行,但是在
ULC
中,它只会以原始大小实例化,并且不会随着对
按钮的调用而改变。SetSize()

我已经研究了
ULC
的bug报告,但没有看到任何相关的和未修复的错误。我尝试调用
ULC
Refresh()
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()
编辑

我现在已经尝试了更多的方法。我去掉了所有的列格式,用简单的
list.InsertColumn(index,label)
调用替换了这3个块。我做的最有用的事情是从
ULC.SetItemWindow()
调用中删除
expand=True
。这似乎将按钮宽度(但不是高度)的控制权返还给了按钮。由于它从150Wx200H开始,当我调用
next
并将其更改为200x200时,按钮溢出到右侧的下一个单元格中。当我再次调用
next
命令大小为80x80时,按钮缩小为150x200,无法设置为小于其初始大小

如果我初始化的按钮比我需要的小,比如说50x30,那么我可以在两个维度上正确设置所有的大小(80,80;200200),但是按钮会溢出到它右边和下面的邻居

您可以看到列表没有刷新任何行。 您还可以看到小部件保持了它原来的左上角位置(也许这是正确的,但我不这么认为)

如果我将
list.Refresh/DoLayout/Layout/Update
添加到
on_按钮
,则它无效

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

这一次(删除行并添加新行)我注意到调整窗口大小(顶层
框架
)强制重画,因此我将
SendSizeEvent
添加到
on_按钮
,现在该按钮工作正常

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

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


另一种说法是:为什么
SendSizeEvent
在将新项目插入列表后强制刷新,而不是在修改现有项目后强制刷新?
如果我知道要执行哪个方法或属性,我可以对
ULC
进行子类化,并扩展特定的方法或属性。我已经试过查看源代码,但我无法了解它的正反两面。

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

此外:添加新窗口时,大小会写入line对象。此操作将不再执行,并且无法通过任何方式手动触发

然而:

如果您像这样调整UltimateListCtrl,它将工作

类UltimateListItemData的函数GetWindowsSize(第2863行):

在代码中,需要使旧的线高度无效,以便重新计算:

def on_button(self, event):
    self.button.SetSize(self.sizes.next())
    self.ultimateList._mainWin.ResetLineDimensions(True)
    self.ultimateList._mainWin.RecalculatePositions()
请注意,这会修改ULC并访问私有变量


Lokla

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

此外:添加新窗口时,大小会写入line对象。此操作将不再执行,并且无法通过任何方式手动触发

然而:

如果您像这样调整UltimateListCtrl,它将工作

类UltimateListItemData的函数GetWindowsSize(第2863行):

在代码中,需要使旧的线高度无效,以便重新计算:

def on_button(self, event):
    self.button.SetSize(self.sizes.next())
    self.ultimateList._mainWin.ResetLineDimensions(True)
    self.ultimateList._mainWin.RecalculatePositions()
请注意,这会修改ULC并访问私有变量


洛卡拉

太好了,非常感谢。我可以说我搞砸了,但我对蟒蛇的经验相对不足