Подписаться на события подкласса wxWidgets в Python - PullRequest
0 голосов
/ 12 января 2020

У меня есть опыт разработки настольных приложений C# (.NET2.0) и за последние годы C для микроконтроллеров. Теперь для GUI приложений на Linux и Windows я изучаю python через wx Python. wxGlade создал код GUI, и я кодировал в него немного обработки событий.

Я нахожусь на Linux Mint 19 Mate, Python 2.7, wx Python 3.0, wxGlade 0.8.0 -1, Stani's Python Editor 0.8.4.

Последняя версия этой программы работала с точки зрения пользователя, но события мыши обрабатывались в кадре, а не на панели (см. вчера вопрос ). Теперь я получил wxGlade для подкласса wxPanel и для использования подкласса во фрейме.

Но мое присоединение обработчиков к событиям в подклассе не работает. Ни панель не окрашивается в белый цвет при запуске программы, ни щелчок мыши не запускают вывод консоли. Что не так с моими звонками self.Bind () ?

# -*- 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 wxDrawPanel(wx.Panel):
    def __init__(self, *args, **kwds):
        # begin wxGlade: wxDrawPanel.__init__
        wx.Panel.__init__(self, *args, **kwds)

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

        print("binding events...")
        self.Bind(wx.EVT_LEFT_DOWN, self.__HandleLEFT_DOWN)
        self.Bind(wx.EVT_LEFT_UP, self.__HandleLEFT_UP)
        self.Bind(wx.EVT_RIGHT_DOWN, self.__HandleRIGHT_DOWN)
        self.Bind(wx.EVT_MOTION, self.__HandleMOTION)
        self.Bind(wx.EVT_PAINT, self.__HandlePAINT)

        self.LmbDown = False
        self.selectedCoord = None
        self.MainFrame = None

    def __set_properties(self):
        # begin wxGlade: wxDrawPanel.__set_properties
        pass
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: wxDrawPanel.__do_layout
        self.Layout()
        # end wxGlade

    def __HandleLEFT_DOWN(self, event):
        self.LmbDown = True
        coord = event.GetPosition()
        print("HandleLEFT_DOWN at ", coord)
        self.selectedCoord = self.MainFrame.FindNearestInVincinity(self.MainFrame.coords, coord, 5)
        if(None == self.selectedCoord):
            self.MainFrame.coords.append(coord)
        else:
            self.MainFrame.coords.remove(self.selectedCoord)
        self.Refresh()
        event.Skip()

    def __HandleLEFT_UP(self, event):
        self.LmbDown = False
        coord = event.GetPosition()
        print("HandleLEFT_UP at ", coord)
        if(None != self.selectedCoord):
            self.MainFrame.coords.append(self.selectedCoord)
            self.selectedCoord = None
            self.Refresh()
        event.Skip()

    def __HandleRIGHT_DOWN(self, event):
        coord = event.GetPosition()
        print("HandleRIGHT_DOWN at ", coord)
        nearestCoord = self.MainFrame.FindNearestInVincinity(self.MainFrame.coords, coord, 5)
        if(None != nearestCoord):
            self.MainFrame.coords.remove(nearestCoord)
            self.Refresh()
        event.Skip()

    def __HandleMOTION(self, event):
        if(None != self.selectedCoord):
            self.selectedCoord = event.GetPosition()
            self.Refresh()
        event.Skip()

    def __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.MainFrame.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)

        if(None != self.selectedCoord):
            shadowPen = wx.Pen("gray")
            dc.SetPen(shadowPen)
            dc.DrawLine(self.selectedCoord[0], self.selectedCoord[1] - 1, self.selectedCoord[0] + 4, self.selectedCoord[1] + 3)
            dc.DrawLine(self.selectedCoord[0], self.selectedCoord[1] + 3, self.selectedCoord[0] + 4, self.selectedCoord[1] - 1)
            dc.SetPen(pen)
            dc.DrawLine(self.selectedCoord[0] - 2, self.selectedCoord[1] - 2, self.selectedCoord[0] + 2, self.selectedCoord[1] + 2)
            dc.DrawLine(self.selectedCoord[0] - 2, self.selectedCoord[1] + 2, self.selectedCoord[0] + 2, self.selectedCoord[1] - 2)

        event.Skip()

# end of class wxDrawPanel
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 = wxDrawPanel(self, wx.ID_ANY)

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

        self.coords = []
        self.DrawPanel.MainFrame = self

    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 FindNearestInVincinity(self, coords, coord, maxDistance):
        if(coord in coords):
            return(coord)

        for d in range(1, maxDistance):
            for i in range(-maxDistance, maxDistance):
                oneCoord = (coord[0] + i, coord[1] - d)
                if(oneCoord in self.coords):
                    return(oneCoord)

                oneCoord = (coord[0] + d, coord[1] + i)
                if(oneCoord in self.coords):
                    return(oneCoord)

                oneCoord = (coord[0] - i, coord[1] + d)
                if(oneCoord in self.coords):
                    return(oneCoord)

                oneCoord = (coord[0] - d, coord[1] - i)
                if(oneCoord in self.coords):
                    return(oneCoord)

        return(None)

# 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()
...