如何 wxPanel.Refresh? [英] How to wxPanel.Refresh?

查看:102
本文介绍了如何 wxPanel.Refresh?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 C# (.NET2.0) 桌面应用程序开发和微控制器 C 语言背景.现在对于 Linux 和 Windows 上的 GUI 应用程序,我正在通过 wxPython 学习 python.

I have a background in C# (.NET2.0) desktop application development and for the last years C for microcontrollers. Now for GUI applications on Linux and Windows, I'm learning python through wxPython.

我使用的是 Linux Mint 19 Mate、Python 2.7、wxPython 3.0、wxGlade 0.8.0-1、Stani 的 Python 编辑器 0.8.4.

I'm on Linux Mint 19 Mate, Python 2.7, wxPython 3.0, wxGlade 0.8.0-1, Stani's Python Editor 0.8.4.

wxGlade 创建了一些 GUI 代码,我在其中编写了一些事件处理.我的问题是我的代码在鼠标事件上调用 wxPanel.Refresh() 但面板没有刷新.我知道绘图代码有效,因为当窗口被埋在另一个窗口下并回到前面时它会起作用.因此,我尝试调用 wxPanel.Hide()wxPanel.Show 而不是刷新,这很有效.

wxGlade created some GUI code and I coded a bit of event handling into it. My problem is that my code calls wxPanel.Refresh() on a mouse event but the panel doesn't get refreshed. I know that the drawing code works because it does when the window is buried under another one and comes back to the front. Therefore I tried to call wxPanel.Hide() and wxPanel.Show instead of refreshing and that works.

但刷新应该独立工作.我对使用隐藏和显示拖动面板上的东西有一种不好的感觉.

But refreshing should work on its own. I have a bad feeling of using hide-and-show for dragging stuff on the panel.

我对 wxPanel.Refresh() 遗漏了什么?

我也试过 wxPanel.Update(),但无济于事.运行时控制台上没有错误.这是完整的代码.有趣的部分是注释掉的第 78 行.

I also tried wxPanel.Update(), but to no avail. There are no errors on the console at runtime. Here's the complete code. Interesting part is the commented-out line 78.

# -*- coding: UTF-8 -*-
#
# generated by wxGlade 0.8.0 on Thu Jan  9 14:00:42 2020
#

import wx

# begin wxGlade: dependencies
# end wxGlade

# begin wxGlade: extracode
# end wxGlade


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((729, 521))

        # Menu Bar
        self.MainMenuBar = wx.MenuBar()
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(wx.ID_ANY, "Open", "")
        wxglade_tmp_menu.Append(wx.ID_ANY, "Close", "")
        wxglade_tmp_menu.AppendSeparator()
        wxglade_tmp_menu.Append(wx.ID_ANY, "Exit", "")
        self.MainMenuBar.Append(wxglade_tmp_menu, "File")
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(wx.ID_ANY, "Preferences", "")
        self.MainMenuBar.Append(wxglade_tmp_menu, "Edit")
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(wx.ID_ANY, "About", "")
        self.MainMenuBar.Append(wxglade_tmp_menu, "?")
        self.SetMenuBar(self.MainMenuBar)
        # Menu Bar end
        self.DrawPanel = wx.Panel(self, wx.ID_ANY)
        self.Bind(wx.EVT_LEFT_DOWN, self.DrawPanel_HandleLEFT_DOWN)
        self.Bind(wx.EVT_LEFT_UP, self.DrawPanel_HandleLEFT_UP)
        self.Bind(wx.EVT_MOTION, self.DrawPanel_HandleMOTION)
        self.Bind(wx.EVT_PAINT, self.DrawPanel_HandlePAINT)

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        self.DrawPanel_LmbDown = False
        self.coords = []

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame")
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        MainSizer = wx.BoxSizer(wx.VERTICAL)
        Statusbar = wx.BoxSizer(wx.HORIZONTAL)
        MainSizer.Add(self.DrawPanel, 0, wx.EXPAND, 0)
        Statusbar.Add((0, 0), 0, 0, 0)
        Statusbar.Add((0, 0), 0, 0, 0)
        Statusbar.Add((0, 0), 0, 0, 0)
        Statusbar.Add((0, 0), 0, 0, 0)
        MainSizer.Add(Statusbar, 0, 0, 0)
        self.SetSizer(MainSizer)
        self.Layout()
        # end wxGlade

    def DrawPanel_HandleLEFT_DOWN(self, event):
        self.DrawPanel_LmbDown = True
        coord = event.GetPosition()
        print("Lmb Down at ", coord[0], ";", coord[1])
        if(coord not in self.coords):
            self.coords.append(coord)
            print(self.coords)
#            self.DrawPanel.Refresh()   # Todo: Find out why Refresh() doesn't work and
            self.DrawPanel.Hide()       #       A combination of Hide() and
            self.DrawPanel.Show()       #       Show() must do the trick.
        event.Skip()

    def DrawPanel_HandleLEFT_UP(self, event):
        self.DrawPanel_LmbDown = False
        coord = event.GetPosition()
        print("Lmb Up at ", coord[0], ";", coord[1])
        event.Skip()

    def DrawPanel_HandleMOTION(self, event):
        if(self.DrawPanel_LmbDown):
            coord = event.GetPosition()
            print("Moving with Lmb Down to ", coord[0], ";", coord[1])
        event.Skip()

    def DrawPanel_HandlePAINT(self, event):
        dc = wx.PaintDC(self)
        brush = wx.Brush("white")
        dc.SetBackground(brush)
        dc.Clear()

        pen = wx.Pen("red")
        dc.SetPen(pen)
        for coord in self.coords:
            dc.DrawLine(coord[0] - 2, coord[1] - 2, coord[0] + 2, coord[1] + 2)
            dc.DrawLine(coord[0] - 2, coord[1] + 2, coord[0] + 2, coord[1] - 2)

        event.Skip()

# end of class MyFrame

class MyApp(wx.App):
    def OnInit(self):
        self.MainFrame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.MainFrame)
        self.MainFrame.Show()
        return True

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

推荐答案

您似乎希望为 self.DrawPanel 处理鼠标和绘制事件,但实际上您正在绑定事件处理程序到框架代替.这有后果.例如,在您的绘制事件处理程序中,self 是框架,而不是 DrawPanel,因此您创建的 dc 将在框架的客户区而不是面板上进行绘制.面板可能会妨碍查看框架上的内容,并阻止某些鼠标事件等.

It appears that you are expecting to handle the mouse and paint events for self.DrawPanel, but you are actually binding the event handlers to the frame instead. This has consequences. For example, in your paint event handler self is the frame, not the DrawPanel so the dc you create will do its drawing on the frame's client area instead of the panel. The panel will likely be getting in the way of seeing what's on the frame, and blocking some of the mouse events, etc.

更好的设计是使绘图面板成为一个单独的类,并将相关的事件绑定和事件处理程序移到该类中.然后框架将只需要创建该新类的实例而不是基础 wx.Panel.

A better design would be to make the draw panel be a separate class, and move the related event bindings and event handlers to that class. Then the frame will just need to create an instance of that new class instead of a base wx.Panel.

这篇关于如何 wxPanel.Refresh?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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