创建自截断椭圆文本 ctrl:如何强制绘制事件
我正在尝试制作一个静态文本,如果对于大小调整器来说太长,则会用椭圆截断自身并仅显示适合的文本。
当您更改必须发送绘画事件的窗口的大小时,我写的内容似乎工作正常,但是在设置标签文本时,我猜绘画事件不会被触发。
我尝试过对我能处理的所有内容(框架、面板、文本本身)调用刷新和更新,以及向框架发送绘画事件,但我无法让它正常工作。
我做了一个快速演示,其中包含一个更改文本标签的按钮。
编辑:已解决
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编辑了上面的代码,现在可以很好地工作,在文本的父级上调用
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!