Végezzük el a következő beállításokat:
Ezek után, ha kódot generálunk, külön állományokba fog minden osztályt kerülni, aminek a nevét átírtunk.
A program mindig a wx.App osztályból származtatott objektummal indul. Alapesetben, ez egy app.py nevű fájlban található.
MVC esetén a wxGalde segítségével a nézetfájlokat egy views könyvtárba szokás generálni. Viszont itt fog létrejönni az app.py állomány is, ami probléma a controllers models és views könyvtárak elérése miatt. Az app.py fájlt a views könyvtárral egy szintre kell tenni. Ilyen esetben az app.py állomány létrehozását magunknak kell megoldani.
Ehhez a következőket tegyük:
projekt01/ `-src/ |-controllers/ |-models/ |-views/ `-app.py
Az app.py fájlból hívjuk a controllers könyvtárban található MainController-t. A MainController-ben példányosítjuk a models könyvtárban található MainModel osztályt, a views könyvtárban található MainFrame osztályt.
Mivel az alkalmazás az src könyvtárból indul, ezért a controllers könyvtárban található kontrollerosztályokban látszanak a többi könyvtárak osztályai.
A .wxg fájl lehet a controllers, models és views könyvtárak mellet, de elhelyezhetjük a views könyvtárban is tetszés szerint.
projekt01/ `-src/ |-controllers/ |-models/ |-views/ `-projekt01.wxg
projekt01/ `-src/ |-controllers/ |-models/ `-views/ `-projekt01.wxg
projekt01/ `-src/ |-controllers/ | `-main_controller.py |-models/ | `-main_model.py |-views/ | `-MainFrame.py | `-projekt01.wxg `-projekt01.py
A views könyvtár állományait a wxGlade programmal készítjük, amíg a többit tetszőleges kódszerkesztővel.
A wxGalde használata során megkötés, hogy nem lehet különböző neve az osztálynak és a fájlnak. Ezért MainFrame.py nevű fájlt hozunk létre, MainFrame osztállyal.
import wx from controllers.main_controller import MainController class Projekt01App(wx.App): def OnInit(self): MainController() return True app = Projekt01App(False) app.MainLoop()
import wx from views.MainFrame import MainFrame from models.main_model import MainModel class MainController: def __init__(self): main_frame = MainFrame(None, wx.ID_ANY, "") main_frame.Show()
class MainModel: def get_name(): return 'János'
# -*- coding: UTF-8 -*- # # generated by wxGlade 1.0.0a9 on Sat Nov 28 23:23:19 2020 # import wx # begin wxGlade: dependencies # end wxGlade # begin wxGlade: extracode # end wxGlade class MainFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MainFrame.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((400, 300)) self.SetTitle("frame") self.panel_1 = wx.Panel(self, wx.ID_ANY) sizer_1 = wx.BoxSizer(wx.VERTICAL) self.button_1 = wx.Button(self.panel_1, wx.ID_ANY, "button_1") sizer_1.Add(self.button_1, 0, wx.ALL, 5) self.panel_1.SetSizer(sizer_1) self.Layout() # end wxGlade # end of class MainFrame
<?xml version="1.0"?> <!-- generated by wxGlade 1.0.0a9 on Sat Nov 28 23:23:14 2020 --> <application encoding="UTF-8" for_version="3.0" header_extension=".h" indent_amount="4" indent_symbol="space" is_template="0" language="python" mark_blocks="1" option="1" overwrite="1" path="./src" source_extension=".cpp" top_window="frame" use_gettext="0" use_new_namespace="1"> <object class="views.MainFrame" name="frame" base="EditFrame" instance_class="MainFrame"> <size>400, 300</size> <title>frame</title> <style>wxDEFAULT_FRAME_STYLE</style> <object class="wxPanel" name="panel_1" base="EditPanel"> <object class="wxBoxSizer" name="sizer_1" base="EditBoxSizer"> <orient>wxVERTICAL</orient> <object class="sizeritem"> <option>0</option> <border>5</border> <flag>wxALL</flag> <object class="wxButton" name="button_1" base="EditButton"> <label>button_1</label> </object> </object> </object> </object> </object> </application>
Ebben a példában, meghagytuk az App osztály generálást. Így az app osztály példánya nem egy kontrollert hív, hanem előbb MainFrame osztályt.
Az osztály nevét így adjuk meg:
views.LeftPanel
A nevet a views. szóval vezettük be. A views egy könyvtár lesz, amit a wxGlade automatikusan létrehoz.
Az alkalmazásosztályt ne tegyük a views könyvtárba, mert felesleges, annak helye az src könyvtár marad.
Az Output path src legyen. Nem szükséges elé pont és per, vagy utána / karakter.
Így következő szerkezetet kapjuk:
tarol/ |--src/ |--views/ | |--LeftPanel.py | `--MainFrame.py `--app.py
Így elkészíthetjük az src könyvtárban a controllers és models könyvtárakat.
tarol/ `--src/ |--controllers/ | `--LeftController.py |--models/ | `--LeftModel.py |--views/ | |--LeftPanel.py | `--MainFrame.py `--app.py
Az eseménykezelést, most ne bízzuk a wxGlade-re, azt mi fogjuk megvalósítani a LeftController.py állományban.
Az app.py fájlhoz nem nyúlunk. Ezt minden esetben újragenerálja a wxGlade.
#!/usr/bin/env python # -*- coding: UTF-8 -*- # # generated by wxGlade 0.9.6 on Tue Aug 11 01:18:08 2020 # # This is an automatically generated file. # Manual changes will be overwritten without warning! import wx from views.MainFrame import MainFrame class TarolApp(wx.App): def OnInit(self): self.frame = MainFrame(None, wx.ID_ANY, "") self.SetTopWindow(self.frame) self.frame.Show() return True # end of class TarolApp if __name__ == "__main__": tarol = TarolApp(0) tarol.MainLoop()
Írjunk egy LeftModel osztályt, amelnyek van egy szoveg adattagja, és egy setValue() metódusa:
class LeftModel: def __init__(self): self.szoveg = None def setValue(self, szoveg): self.szoveg = szoveg print("Model ok")
Írjunk egy LeftController osztályt:
import wx from views.LeftPanel import LeftPanel from models.LeftModel import LeftModel class LeftController: def __init__(self, panel: LeftPanel): self.panel = panel self.panel.Bind(wx.EVT_BUTTON, self.onClickGoButton, self.panel.goButton) self.leftModel = LeftModel() def onClickGoButton(self, event): valtozo = self.panel.text1.GetValue() self.leftModel.setValue(valtozo)
Legyen egy Panel:
# -*- coding: UTF-8 -*- # # generated by wxGlade 0.9.6 on Tue Aug 11 01:26:08 2020 # import wx # begin wxGlade: dependencies # end wxGlade # begin wxGlade: extracode # end wxGlade class LeftPanel(wx.Panel): def __init__(self, *args, **kwds): # begin wxGlade: LeftPanel.__init__ kwds["style"] = kwds.get("style", 0) wx.Panel.__init__(self, *args, **kwds) self.text1 = wx.TextCtrl(self, wx.ID_ANY, "") self.goButton = wx.Button(self, wx.ID_ANY, "Mehet") self.__set_properties() self.__do_layout() # end wxGlade def __set_properties(self): # begin wxGlade: LeftPanel.__set_properties pass # end wxGlade def __do_layout(self): # begin wxGlade: LeftPanel.__do_layout sizer_2 = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, u"Tevékenységek"), wx.VERTICAL) sizer_2.Add(self.text1, 0, wx.ALL | wx.EXPAND, 6) sizer_2.Add(self.goButton, 0, wx.ALL | wx.EXPAND, 6) self.SetSizer(sizer_2) sizer_2.Fit(self) self.Layout() # end wxGlade # end of class LeftPanel
Hívjuk meg a MainFrame osztályban a LeftController-t.
# -*- coding: UTF-8 -*- # # generated by wxGlade 0.9.6 on Mon Aug 10 18:01:18 2020 # import wx from controllers.LeftController import LeftController # begin wxGlade: dependencies from views.LeftPanel import LeftPanel # end wxGlade # begin wxGlade: extracode # end wxGlade class MainFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MainFrame.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((400, 300)) self.leftPanel = LeftPanel(self, wx.ID_ANY) self.__set_properties() self.__do_layout() # end wxGlade LeftController(self.leftPanel) def __set_properties(self): # begin wxGlade: MainFrame.__set_properties self.SetTitle("frame") # end wxGlade def __do_layout(self): # begin wxGlade: MainFrame.__do_layout sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_1.Add(self.leftPanel, 1, wx.ALL | wx.EXPAND, 6) self.SetSizer(sizer_1) self.Layout() # end wxGlade # end of class MainFrame