首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何wxPanel.Refresh?

如何wxPanel.Refresh?
EN

Stack Overflow用户
提问于 2020-01-10 21:36:04
回答 1查看 394关注 0票数 0

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

我在Linux 19 Mate上,Python2.7,wxPython 3.0,wxGlade 0.8.0-1,Stani的Python 0.8.4。

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

但清爽应该自己起作用。我有一种不好的感觉,用隐藏和显示来拖拽面板上的东西。

关于wxPanel.Refresh(),我错过了什么

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

代码语言:javascript
复制
# -*- 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()
EN

回答 1

Stack Overflow用户

发布于 2020-01-10 23:53:37

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59689325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档