Dialog的ShowModal()不会发送EVT_PAINT [英] Dialog's ShowModal() won't send EVT_PAINT

查看:152
本文介绍了Dialog的ShowModal()不会发送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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆