创建自截断椭圆文本 ctrl:如何强制绘制事件

发布于 2024-12-25 01:20:10 字数 2590 浏览 0 评论 0原文

我正在尝试制作一个静态文本,如果对于大小调整器来说太长,则会用椭圆截断自身并仅显示适合的文本。

当您更改必须发送绘画事件的窗口的大小时,我写的内容似乎工作正常,但是在设置标签文本时,我猜绘画事件不会被触发。

我尝试过对我能处理的所有内容(框架、面板、文本本身)调用刷新和更新,以及向框架发送绘画事件,但我无法让它正常工作。

我做了一个快速演示,其中包含一个更改文本标签的按钮。

编辑:已解决

import wx
from wx.lib.stattext import GenStaticText as StaticText

class EllipticStaticText2(StaticText):
    def __init__(self,parent,id=wx.ID_ANY,label='',width=None,pos=wx.DefaultPosition,size=wx.DefaultSize,style=0,name="ellipticstatictext2"):
        self.actual_label= label
        self.parent= parent
        self.width= width
        StaticText.__init__(self,parent,id,label,pos,size,style,name)
        self.Bind(wx.EVT_PAINT, self.OnPaint2)

    def SetLabel(self,label):
        self.actual_label= label
        StaticText.SetLabel(self,label)
        self.parent.Layout()

    def SetLabelText(self,label):
        self.actual_label= label
        StaticText.SetLabelText(self,label)
        self.parent.Layout()

    def OnPaint2(self,event):
        dc= wx.PaintDC(self)
        displaylabel= self.actual_label
        x,y= dc.GetTextExtent(displaylabel)
        self.w,self.h= self.GetSize()
        if x>self.w:
            while x>self.w:
                displaylabel= displaylabel[:-1]
                x,y= dc.GetTextExtent(displaylabel+"...")
            StaticText.SetLabel(self,displaylabel+"...")
        else:
            StaticText.SetLabel(self,displaylabel)
        event.Skip()


class CustomFrame(wx.Frame):
    def __init__(self,parent,id,name,size):
        wx.Frame.__init__(self,parent,id,name,size)

        self.panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.index= 35

        self.elliptic = EllipticStaticText2(self.panel, -1, r"long string."*20)
        whitePanel = wx.Panel(self.panel, -1)
        whitePanel.SetBackgroundColour(wx.WHITE)

        sizer.Add(self.elliptic, 0, wx.ALL|wx.EXPAND, 10)
        btn= wx.Button(self.panel,-1,"change")
        sizer.Add(btn,0,wx.ALL|wx.EXPAND, 10)
        sizer.Add(whitePanel, 1, wx.ALL|wx.EXPAND, 10)

        btn.Bind(wx.EVT_BUTTON,self.button)

        self.panel.SetSizer(sizer)
        sizer.Layout()

    def button(self,event):
        self.elliptic.SetLabel(chr(self.index)*100)
        self.index+=1
        self.Refresh()
        self.panel.Refresh()
        self.elliptic.Refresh()

if __name__ == "__main__":
    app = wx.PySimpleApp()

    frame = CustomFrame(None, -1, "EllipticStaticText", size=(700, 300))

    frame.CenterOnScreen()
    frame.Show()

    app.MainLoop()

I'm trying make a static text which if too long for the sizer, will truncate itself with an ellipse and just show the text which will fit.

What I've written seems to work fine when you change the size of the window which must be sending paint events, but when setting the label text I guess a paint event doesn't get fired.

I've tried calling Refresh and Update on everything I can thing of (Frame, panel, the text itself) as well as sending a paint event to the frame but I cant get it to work correctly.

I made a quick demo with a button to change the text label.

EDIT: SOLVED

import wx
from wx.lib.stattext import GenStaticText as StaticText

class EllipticStaticText2(StaticText):
    def __init__(self,parent,id=wx.ID_ANY,label='',width=None,pos=wx.DefaultPosition,size=wx.DefaultSize,style=0,name="ellipticstatictext2"):
        self.actual_label= label
        self.parent= parent
        self.width= width
        StaticText.__init__(self,parent,id,label,pos,size,style,name)
        self.Bind(wx.EVT_PAINT, self.OnPaint2)

    def SetLabel(self,label):
        self.actual_label= label
        StaticText.SetLabel(self,label)
        self.parent.Layout()

    def SetLabelText(self,label):
        self.actual_label= label
        StaticText.SetLabelText(self,label)
        self.parent.Layout()

    def OnPaint2(self,event):
        dc= wx.PaintDC(self)
        displaylabel= self.actual_label
        x,y= dc.GetTextExtent(displaylabel)
        self.w,self.h= self.GetSize()
        if x>self.w:
            while x>self.w:
                displaylabel= displaylabel[:-1]
                x,y= dc.GetTextExtent(displaylabel+"...")
            StaticText.SetLabel(self,displaylabel+"...")
        else:
            StaticText.SetLabel(self,displaylabel)
        event.Skip()


class CustomFrame(wx.Frame):
    def __init__(self,parent,id,name,size):
        wx.Frame.__init__(self,parent,id,name,size)

        self.panel = wx.Panel(self, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.index= 35

        self.elliptic = EllipticStaticText2(self.panel, -1, r"long string."*20)
        whitePanel = wx.Panel(self.panel, -1)
        whitePanel.SetBackgroundColour(wx.WHITE)

        sizer.Add(self.elliptic, 0, wx.ALL|wx.EXPAND, 10)
        btn= wx.Button(self.panel,-1,"change")
        sizer.Add(btn,0,wx.ALL|wx.EXPAND, 10)
        sizer.Add(whitePanel, 1, wx.ALL|wx.EXPAND, 10)

        btn.Bind(wx.EVT_BUTTON,self.button)

        self.panel.SetSizer(sizer)
        sizer.Layout()

    def button(self,event):
        self.elliptic.SetLabel(chr(self.index)*100)
        self.index+=1
        self.Refresh()
        self.panel.Refresh()
        self.elliptic.Refresh()

if __name__ == "__main__":
    app = wx.PySimpleApp()

    frame = CustomFrame(None, -1, "EllipticStaticText", size=(700, 300))

    frame.CenterOnScreen()
    frame.Show()

    app.MainLoop()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

铁轨上的流浪者 2025-01-01 01:20:10

编辑了上面的代码,现在可以很好地工作,在文本的父级上调用 Layout() 就可以了。我总是忘记那个方法!

Edited the code above which now works nicely, calling Layout() on the text's parent did the trick.. I keep forgetting about that method!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文