Dialog公司的ShowModal()将不会发送EVT_PAINT(Dialog's Sh

2019-10-21 22:42发布

WX版本:2.8.12.1

我试图建立一个除芯对话框(背景,按钮,位图边防等),但上ShowModal()不发Paint事件。

它与Show()超级种子wx.PopupTransientWindow ,但不Show()ShowModal()wx.Dialog

如果你运行的例子,打开对话框,单击这两个按钮,你会得到在终端上:

send refresh
Clicked OK/CANCEL

"Paint Event""Draw Function"将不被打印出来。 "send refresh"表示手动Refresh()已经发出; 这应该发出wx.EVT_PAINT

如果OnPaint被绑定到wx.EVT_SHOW的功能将被调用, wx.BufferedPaintDC将要设置正确,但它不会改变任何东西可见。

#!/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()

Answer 1:

你已经绑定您的油漆事件处理程序的对话框,但该对话框有一个面板完全覆盖对话框。 由于对话框的表面不会暴露(因为它是面板下),那么它永远不需要油漆,所以它永远不会临危来自系统的绘画事件。

在大多数情况下,你不需要面板在对话框顶部的元素,所以你可能要删除它,然后替换所有self.panel只有在代码的那部分self



Answer 2:

继提示上绘制框架的面板内 :

  • 我错了Paint事件的绑定

     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事件; 导致self从未获得意识到Paint事件的。

  • 和画布的父母:

     dc = wx.BufferedPaintDC(self.panel) 

    打从一点点的子类后wx.PopupWindow (这就造成了严重大小的窗口,我不能在框架正确中心)我意识到DC正在呈现的面板下方。 这让SENCE因为self.panel是一个孩子self ,所以只有self正在画。


不是一个错误 ,但是,油漆事件,似乎在面板或对话框回来到他们的默认大小。 如果面板贴合,对话框的大小时,窗口会在Paint事件再次集中,然后新的油漆活动将升起,闪烁会出现。 由于这是一个静态参数的对话框,其尺寸可以是固定的与该在的端self._layout()

self.panel.Fit()
minSize = self.panel.GetSize()
self.SetMinSize(minSize)
self.SetMaxSize(minSize)


文章来源: Dialog's ShowModal() won't send EVT_PAINT