Dialog的ShowModal()不会发送EVT_PAINT [英] Dialog's ShowModal() won't send EVT_PAINT
问题描述
wx版本:2.8.12.1
wx version: 2.8.12.1
我正在尝试构建一个颓废的对话框(背景,按钮,位图边框等),但是在 ShowModal()
Paint事件不发出。
I'm trying to build a decored Dialog (Background, Buttons, Bitmap Border, etc) but on ShowModal()
the Paint event is not issued.
它与 Show()
超级种子 wx.PopupTransientWindow
,但不与 Show()
或 ShowModal()
在 wx.Dialog
It works with Show()
super seeding wx.PopupTransientWindow
, but not with Show()
or ShowModal()
on wx.Dialog
如果运行示例,打开对话框并单击两个按钮中的任一个,您将得到终端:
If you run the example, open the Dialog and click either of the two buttons, you'll get on the terminal:
send refresh
Clicked OK/CANCEL
Paint Event
或绘图功能
将不会打印。
发送刷新
表示手册 Refresh()
已发出;并且应该发出一个 wx.EVT_PAINT
。
"Paint Event"
or "Draw Function"
won't be printed.
"send refresh"
indicates that a manual Refresh()
has been issued; and that should issue an wx.EVT_PAINT
.
如果 OnPaint
绑定到 wx.EVT_SHOW
函数将被调用, wx.BufferedPaintDC
将被正确设置,但它不会改变任何可见的。
If OnPaint
is binded to wx.EVT_SHOW
the functions will be called, the wx.BufferedPaintDC
will be correctly set, but it won't change anything visible.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import wx
def GetThemeTools(borderWidth, backgrounColour):
return {
'Pens': {
'DarkRectSolidBorder': wx.Pen( wx.Colour(67, 67, 67), borderWidth),
},
'Brushes': {
'Background': wx.Brush(backgrounColour),
'RectBoxFilling': wx.Brush( wx.Colour(119,120,119) ),
},
'ForegroundColor': wx.Colour(241,241,241),
'BackgroundColor': 'WHITE',
'Fonts': {
'Brief': wx.Font( pointSize=12,
family=wx.FONTFAMILY_SWISS,
style=wx.FONTSTYLE_NORMAL,
weight=wx.FONTWEIGHT_NORMAL,
encoding=wx.FONTENCODING_UTF8
),
},
}
class ConfirmDialog(wx.Dialog):
def __init__(self, parent, text="",
margin=10, borderRadio=10):
wx.Dialog.__init__(self, parent, style=wx.STAY_ON_TOP)
# Get data to show
self.parent = parent
self._margin = margin
self._borderRadio = borderRadio
self._text = text
self._font = None
self.initializeTools()
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SHOW, self._sendRefresh)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
self._setWidgets()
self._layout()
wx.CallAfter(self.Refresh)
def _sendRefresh(self, e):
if self.IsShown():
print("send refresh")
self.Refresh()
def _setWidgets(self):
self.panel = wx.Panel(self)
self.message = wx.StaticText(self.panel, label=self.GetText())
self.message.SetForegroundColour(self.tools['ForegroundColor'])
self.message.SetBackgroundColour(self.tools['BackgroundColor'])
self.cancelBtn = wx.Button(self.panel, id=wx.ID_CANCEL, label="Cancel")
self.okBtn = wx.Button(self.panel, id=wx.ID_OK, label="Ok")
def _layout(self):
self.vSizer = wx.BoxSizer(wx.VERTICAL)
self.buttonsSizer = wx.BoxSizer(wx.HORIZONTAL)
self.buttonsSizer.Add(self.okBtn)
self.buttonsSizer.AddSpacer(20)
self.buttonsSizer.Add(self.cancelBtn)
self.vSizer.Add(self.message, 0, wx.CENTER|wx.BOTTOM, 5)
self.vSizer.Add(self.buttonsSizer, 0, wx.CENTER|wx.TOP, 5)
self.panel.SetSizer(self.vSizer)
self.vSizer.Fit(self.panel)
def SetMargin(self, margin):
self._margin = margin
self.Refresh()
def GetMargin(self):
return self._margin
def SetBorderRadio(self, borderRadio):
self._borderRadio = borderRadio
self.Refresh()
def GetBorderRadio(self):
return self._borderRadio
def SetText(self, text):
self._text = text
self.Refresh()
def GetText(self):
return self._text
def GetFont(self):
if not self._font:
self._font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
return self._font
def initializeTools(self):
self.borderWidth = 6
backColour = self.GetBackgroundColour()
self.tools = GetThemeTools(self.borderWidth, backColour)
self._font = self.tools['Fonts']['Brief']
def OnPaint(self, event):
print("Paint Event")
dc = wx.BufferedPaintDC(self)
self.Draw(dc)
event.Skip()
def Draw(self, dc):
print("Draw Function")
margin = self.GetMargin()
borderRadio = self.GetBorderRadio()
text = self.GetText()
self.Layout()
dc.SetBackground(self.tools['Brushes']['Background'])
dc.SetFont(self.GetFont())
dc.SetTextBackground(self.tools['BackgroundColor'])
dc.Clear()
(H, W) = self.GetSize()
# Draw Border
dc.SetPen(self.tools['Pens']['DarkRectSolidBorder'])
dc.SetBrush(self.tools['Brushes']['RectBoxFilling'])
dc.DrawRoundedRectangle( 0, 0, H, W, borderRadio)
def OnEraseBackground(self, event):
pass
class AppFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Custom Dialog Test")
panel = wx.Panel(self)
frameSizer = wx.BoxSizer(wx.VERTICAL)
panelSizer = wx.BoxSizer(wx.VERTICAL)
btn = wx.Button(panel, label="Show Dialog")
btn.Bind(wx.EVT_BUTTON, self.ShowDlg)
panelSizer.Add(btn, 0, wx.ALL, 20)
panel.SetSizer(panelSizer)
self.SetSizer(frameSizer)
panelSizer.Fit(panel)
self.Layout()
self.Show()
def ShowDlg(self, event):
dia = ConfirmDialog(self, "Custom Dialog\nTest\nThird Line")
if dia.ShowModal() == wx.ID_OK:
print("Clicked OK")
else:
print("Clicked CANCEL")
app = wx.App(False)
frame = AppFrame()
app.MainLoop()
推荐答案
关于在框架内绘制面板:
-
我错了绑定油漆事件
I got wrong the bind of the Paint Event
self.panel.Bind(wx.EVT_PAINT, self.OnPaint)
self.panel.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
由于某些原因我还没有完全得到在 self.Bind vs self.button.Bind )为什么面板不会 Skip()
Paint Event;导致 self
从未察觉到Paint Event。
For some reason I still don't fully get (examples at self.Bind vs self.button.Bind) why the panel won't Skip()
the Paint Event; leading to self
never getting aware of the Paint Event.
画布的父母身份: / p>
And the parenthood of the canvas:
dc = wx.BufferedPaintDC(self.panel)
从 wx.PopupWindow
(导致我的大小不正确的中心窗口,在框架中)我意识到DC正在面板之下。因为 self.panel
是 self
的孩子,所以只有 self
正在画。
After playing a little bit subclassing from wx.PopupWindow
(which resulted in a badly sized Window that I couldn't properly center in the frame) I realized that the DC was being rendered below the panel. It makes sence since self.panel
is a child of self
, so only self
was being painted.
不是错误,但在绘制事件中,似乎面板或对话框恢复到默认大小。如果面板合适,则调整对话框的大小,并且窗口在Paint Event中再次居中,然后将引发新的Paint事件,并显示闪烁。由于这是一个参数化的静态对话框,因此可以在 self._layout()
的末尾修改维度:
Not an Error but on the Paint Event, it seems the panel or dialog gets back to their default size. If the panel is fit, the dialog is resized, and the window is centered again in the Paint Event, then new Paint Events will be raised and a flicker will appear. Since this is an parameterized static dialog, the dimensions can be fixed with this at the end of self._layout()
:
self.panel.Fit()
minSize = self.panel.GetSize()
self.SetMinSize(minSize)
self.SetMaxSize(minSize)
这篇关于Dialog的ShowModal()不会发送EVT_PAINT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!