wxPython - menu a nástrojová lišta
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

wxPython - menu a nástrojová lištawxPython - menu a nástrojová lišta

 

wxPython - menu a nástrojová lišta

Google       Google       21. 10. 2008       25 474×

Ve druhém dílu seriálu o wxPythonu se naučíme, jak vytvářet menu a nástrojovou lištu (toolbar).

Reklama
Reklama

Vytváření MenuBaru

Menu je jedno z nejviditelnějších částí celé GUI aplikace. Zatímco v konzolových aplikacích si musíte pamatovat všechny příkazy, v menu naleznete všechny příkazy roztříděné do logických částí. K vytvoření menu potřebujeme tři komponenty: wx.MenuBar, wx.Menu a wx.MenuItem.

Vytvoření jednoduchého menu ve wxPythonu je opravdu jednoduché. Zabere to pouze několik řádek kódu.

import wx

class SimpleMenu(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        menubar = wx.MenuBar()
        file = wx.Menu()
        file.Append(-1, 'Quit', 'Quit application')
        menubar.Append(file, '&File')
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)

app = wx.App()
SimpleMenu(None, -1, 'simple menu example')
app.MainLoop()

Jako obvykle si kód rozebereme řádku po řádce.

menubar = wx.MenuBar()

Nejprve vytvoříme objekt wx.MenuBar.

file = wx.Menu()

Pak vytvoříme objekt wx.Menu.

file.Append(-1, 'Quit', 'Quit application')

Přidáme položku do menu. První parametr je id položky. Druhý parametr je popisek položky a třetí parametr je pomocný popisek, který se zobrazí ve statusbaru, pokud je položka vybrána. V tomto příkladě jsme nevyužili objekt wx.MenuItem. Tento objekt byl za nás vytvořen metodou Append(). Později se naučíme wx.MenuItem používat.

menubar.Append(file, '&File')
self.SetMenuBar(menubar)

Poté přidáme menu do menubaru. Znak & představuje klávesovou zkratku. Znak, který následuje po &, bude podtržený. Tímto způsobem je menu přístupné pod klávesovou zkratkou alt + F. Nakonec zavoláme metodu SetMenuBar(). Tato metoda vykreslí menubar do okna.

Ikony, zkratky a události

Na několika následujících řádkách vylepšíme náš předchozí příklad. Ukážeme si, jak jednotlivým položkám v menu přidat ikonu. Ikony dělají naši aplikaci atraktivnější pro oči uživatele a také jim pomáhají pochopit, co přesně daná položka dělá. Také si ukážeme, jak přiřazovat naší aplikaci klávesové zkratky. Klávesové zkratky mohou velmi urychlit uživatelům práci s aplikací. Jednou z nejpoužívanějších klávesových zkratek je Ctrl + s. Je daleko rychlejší zmáčknout kombinaci těchto kláves, než najet myší na menu, otevřít ho a kliknou na Uložit. Také se velmi stručně řekneme něco o událostech a o tom, jak je zachytit a zpracovat.

import wx

class MenuExample(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        menubar = wx.MenuBar()
        file = wx.Menu()
        quit = wx.MenuItem(file, 1, '&QuittCtrl+Q')
        quit.SetBitmap(wx.Bitmap('icons/exit.png'))
        file.AppendItem(quit)

        self.Bind(wx.EVT_MENU, self.OnQuit, id=1)

        menubar.Append(file, '&File')
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)

    def OnQuit(self, event):
        self.Close()

app = wx.App()
MenuExample(None, -1, '')
app.MainLoop()

Analýza kódu:

quit = wx.MenuItem(file, 1, '&QuittCtrl+Q')
quit.SetBitmap(wx.Bitmap('icons/exit.png'))
file.AppendItem(quit)

Pokud chceme přidat ikonku nějaké položce v menu, musíme už použít objekt wx.MenuItem (nevystačíme si tedy s metodou Apend()). Znak následující po & je klávesová zkratka. V tomto případě se tedy aplikace zavře, pokud uživatel stiskne kombinaci Ctrl + q. Ikonu definujeme pomocí metody SetBitmap().

Jelikož jsme položku menu vytvářeli pomocí objektu wx.MenuItem a ne pomocí metody Append(), musíme danou položku ještě do menu přidat. Děje se tak pomocí metody AppendItem().

self.Bind(wx.EVT_MENU, self.OnQuit, id=1)

Pokud klikneme na položku quit nebo stiskneme kombinaci kláves Ctrl + q, wxPython vygeneruje událost wx.EVT_MENU. My jsme této události přiřadili metodu self.OnQuit. Třetím parametrem metody Bind je id. Menubar bude mít totiž obvykle více než jednu položku a proto musí mít každá položka unikátní id. O událostech si řekneme více později.

Submenu

Každé menu může mít v sobě submenu (menu vnořené v menu). Tímto způsobem můžeme rozdělit podobné příkazy do jednotlivých skupin. Například můžeme položky Projekt, Editace a Vzhled vložit do submenu nazvaného Panely nástrojů. V rámci menu můžeme jednotlivé položky od sebe oddělit separátorem. Je běžná záležitost, že položky Nový soubor, Otevřít a Uložit jsou odděleny separátorem od položek Tisk nebo Zavřít. V následujícím příkladu si ukážeme, jak vytvořit submenu a jak vložit do menu separátor.

import wx

ID_QUIT = 1

class SubmenuExample(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(350, 250))

        menubar = wx.MenuBar()

        file = wx.Menu()
        file.Append(-1, '&New')
        file.Append(-1, '&Open')
        file.Append(-1, '&Save')
        file.AppendSeparator()

        imp = wx.Menu()
        imp.Append(-1, 'Import newsfeed list...')
        imp.Append(-1, 'Import bookmarks...')
        imp.Append(-1, 'Import mail...')

        file.AppendMenu(-1, 'I&mport', imp)

        quit = wx.MenuItem(file, ID_QUIT, '&QuittCtrl+W')
        quit.SetBitmap(wx.Bitmap('icons/exit.png'))
        file.AppendItem(quit)

        self.Bind(wx.EVT_MENU, self.OnQuit, id=ID_QUIT)

        menubar.Append(file, '&File')
        self.SetMenuBar(menubar)

        self.Centre()
        self.Show(True)

    def OnQuit(self, event):
        self.Close()

app = wx.App()
SubmenuExample(None, -1, 'Submenu')
app.MainLoop()

Následuje analýza kódu:

file.AppendSeparator()

Separátor do menu vložíme pomocí metody AppendSeparator.

imp = wx.Menu()
imp.Append(-1, 'Import newsfeed list...')
imp.Append(-1, 'Import bookmarks...')
imp.Append(-1, 'Import mail...')

file.AppendMenu(-1, 'I&mport', imp)

Vytváření submenu je opravdu triviální záležitost. Nejprve vytvoříme objekt wx.Menu, do kterého vložíme požadované položky. Nakonec vložíme submenu do hlavního menu zavoláním metody AppendMenu().

Různé druhy menu

Existují tři druhy menu:

  • Normální menu
  • Zaškrtávací (check) menu
  • Přepínací (radio) menu
import wx

ID_STAT = 1
ID_TOOL = 2

class CheckMenuItem(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(350, 250))

        menubar = wx.MenuBar()
        file = wx.Menu()
        view = wx.Menu()
        self.shst = view.Append(ID_STAT, 'Show statubar', 'Show Statusbar', kind=wx.ITEM_CHECK)
        self.shtl = view.Append(ID_TOOL, 'Show toolbar', 'Show Toolbar', kind=wx.ITEM_CHECK)
        view.Check(ID_STAT, True)
        view.Check(ID_TOOL, True)

        self.Bind(wx.EVT_MENU, self.ToggleStatusBar, id=ID_STAT)
        self.Bind(wx.EVT_MENU, self.ToggleToolBar, id=ID_TOOL)




        menubar.Append(file, '&File')
        menubar.Append(view, '&View')
        self.SetMenuBar(menubar)

        self.toolbar = self.CreateToolBar()
        self.toolbar.AddLabelTool(3, '', wx.Bitmap('icons/quit.png'))
        self.toolbar.Realize()
        self.statusbar = self.CreateStatusBar()
        self.Centre()
        self.Show(True)

    def ToggleStatusBar(self, event):
        if self.shst.IsChecked():
            self.statusbar.Show()
        else:
            self.statusbar.Hide()

    def ToggleToolBar(self, event):
        if self.shtl.IsChecked():
            self.toolbar.Show()
        else:
            self.toolbar.Hide()

app = wx.App()
CheckMenuItem(None, -1, 'check menu item')
app.MainLoop()

Následuje analýza kódu:

self.shst = view.Append(ID_STAT, 'Show statubar', 'Show Statusbar', kind=wx.ITEM_CHECK)
self.shtl = view.Append(ID_TOOL, 'Show toolbar', 'Show Toolbar', kind=wx.ITEM_CHECK)

Pokud chceme do menu přidat položku typu „zaškrtávátka“, musíme specifikovat parametr kind = wx.ITEM_CHECK (standardní hodnota je wx.ITEM_NORMAL). Metoda Append vrací wx.MenuItem.

view.Check(ID_STAT, True)
view.Check(ID_TOOL, True)

Když se aplikace spustí, je vidět nástrojová lišta (toolbar) i statusbar. Proto musíme obě položky zaškrtnout zavoláním metody Check().

def ToggleStatusBar(self, event):
    if self.shst.IsChecked():
        self.statusbar.Show()
    else:
        self.statusbar.Hide()

Schováme nebo zobrazíme statusbar na základě toho, jestli je daná položka menu zaškrtnuta nebo ne. To zjistíme zavoláním metody IsChecked().

Kontextové menu

Kontextové menu je vlastně menu bez menubaru. Objeví se vždy tam, kde je potřeba. Znáte to například z webového prohlížeče Firefox. Když kliknete pravým tlačítkem na stránku, objeví se kontextové menu s nabídkami jako „Ukázat zdrojový kód“ apod. Následující kód ukazuje, jak takové menu vytvořit.

import wx


class MyPopupMenu(wx.Menu):
    def __init__(self, parent):
        wx.Menu.__init__(self)

        self.parent = parent

        minimize = wx.MenuItem(self, wx.NewId(), 'Minimize')
        self.AppendItem(minimize)
        self.Bind(wx.EVT_MENU, self.OnMinimize, id=minimize.GetId())

        close = wx.MenuItem(self, wx.NewId(), 'Close')
        self.AppendItem(close)
        self.Bind(wx.EVT_MENU, self.OnClose, id=close.GetId())


    def OnMinimize(self, event):
        self.parent.Iconize()

    def OnClose(self, event):
        self.parent.Close()


class ContextMenu(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)

        self.Center()
        self.Show()

    def OnRightDown(self, event):
        self.PopupMenu(MyPopupMenu(self), event.GetPosition())


app = wx.App()
frame = ContextMenu(None, -1, 'context menu')
app.MainLoop()

Následuje analýza kódu:

class MyPopupMenu(wx.Menu):
    def __init__(self, parent):
        wx.Menu.__init__(self)

Vytváříme vlastní třídu, která dědí z wx.Menu. V této třídě definujeme dvě metody: OnClose a OnMinimize.

self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)

Pokud v okně klikneme pravým tlačítkem myši, zavoláme tím metodu OnRightDown(). K tomu používáme ovladač wx.EVT_RIGHT_DOWN.

def OnRightDown(self, event):
     self.PopupMenu(MyPopupMenu(self), event.GetPosition())

V metodě OnRightDown() voláme metodu PopupMenu. Tato metoda zobrazí kontextové menu. První parametr je menu, které se zobrazí, a druhý parametr je pozice, kde se kontextové menu objeví. Správně by se mělo objevit na aktuální pozici myši a tu získáme, pokud zavoláme metodu GetPosition().

Nástrojová lišta

Do menu se vkládá většina funkcí, které daná aplikace zvládne. Nástrojová lišta (Toolbar) poskytuje přístup k těm nejpoužívanějším.

CreateToolBar(long style=-1, int winid=-1, String name=ToolBarNameStr)

Abychom vytvořili nástrojovou lištu, musíme zavolat metodu CreateToolBar.

import wx

class SimpleToolbar(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 200))

        toolbar = self.CreateToolBar()
        toolbar.AddLabelTool(wx.ID_EXIT, '', wx.Bitmap('../icons/exit.png'))
        toolbar.Realize()

        self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)

        self.Centre()
        self.Show(True)

    def OnExit(self, event):
        self.Close()


app = wx.App()
SimpleToolbar(None, -1, 'simple toolbar')
app.MainLoop()

Analýza kódu:

toolbar.AddLabelTool(wx.ID_EXIT, '', wx.Bitmap('../icons/exit.png'))

Tlačítka do nástrojové lišty přidáváme pomocí metody AddLabelTool.

toolbar.Realize()

Poté, co do nástrojové lišty přidáme všechny tlačítka, musíme zavolat metodu Realize. Tím vykreslíme nástrojovou lištu do okna.

self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)

Ke zpracování události kliknutí na nástrojovou lištu se používá ovladač wx.EVT_TOOL.

Pokud chceme, aby naše aplikace měla dvě nástrojové lišty, musíme to udělat jinak:

import wx

class Toolbars(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 200))

        vbox = wx.BoxSizer(wx.VERTICAL)

        toolbar1 = wx.ToolBar(self, -1)
        toolbar1.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('../icons/new.png'))
        toolbar1.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('../icons/open.png'))
        toolbar1.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('../icons/save.png'))
        toolbar1.Realize()

        toolbar2 = wx.ToolBar(self, -1)
        toolbar2.AddLabelTool(wx.ID_EXIT, '', wx.Bitmap('../icons/exit.png'))
        toolbar2.Realize()

        vbox.Add(toolbar1, 0, wx.EXPAND)
        vbox.Add(toolbar2, 0, wx.EXPAND)

        self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)

        self.SetSizer(vbox)
        self.Centre()
        self.Show(True)

    def OnExit(self, event):
        self.Close()


app = wx.App()
Toolbars(None, -1, 'toolbars')
app.MainLoop()

Vytvořili jsme dvě instance třídy wx.ToolBar a umístili jsme je do vertikálního boxu.

toolbar1 = wx.ToolBar(self, -1)
...
toolbar2 = wx.ToolBar(self, -1)

Doposud jsme vytvářeli horizontální nástrojové lišty, ale občas může nastat situace, kdy budeme chtít vytvořit vertikální lištu.

import wx

class VerticalToolbar(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(240, 300))

        toolbar = self.CreateToolBar(wx.TB_VERTICAL)
        toolbar.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('new.bmp'))
        toolbar.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('open.bmp'))
        toolbar.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('save.bmp'))
        toolbar.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('quit.bmp'))

        toolbar.Realize()


        self.Centre()
        self.Show(True)

    def OnExit(self, event):
        self.Close()


app = wx.App()
VerticalToolbar(None, -1, 'vertical toolbar')
app.MainLoop()

Analýza kódu:

toolbar = self.CreateToolBar(wx.TB_VERTICAL)

Vertikální lištu vytváříme pomocí stylu wx.TB_VERTICAL.

V následujícím příkladu si ukážeme jak zablokovat a odblokovat jednotlivá tlačítka nástrojové lišty. Také se naučíme jak do nástrojové lišty vložit separátor.

import wx

class EnableDisable(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

        self.count = 5

        self.toolbar = self.CreateToolBar()
        self.toolbar.AddLabelTool(wx.ID_UNDO, '', wx.Bitmap('../icons/undo.png'))
        self.toolbar.AddLabelTool(wx.ID_REDO, '', wx.Bitmap('../icons/redo.png'))
        self.toolbar.EnableTool(wx.ID_REDO, False)
        self.toolbar.AddSeparator()
        self.toolbar.AddLabelTool(wx.ID_EXIT, '', wx.Bitmap('../icons/exit.png'))
        self.toolbar.Realize()

        self.Bind(wx.EVT_TOOL, self.OnExit, id=wx.ID_EXIT)
        self.Bind(wx.EVT_TOOL, self.OnUndo, id=wx.ID_UNDO)
        self.Bind(wx.EVT_TOOL, self.OnRedo, id=wx.ID_REDO)

        self.Centre()
        self.Show(True)

    def OnUndo(self, event):
        if self.count > 1 and self.count <= 5:
            self.count = self.count - 1

        if self.count == 1:
            self.toolbar.EnableTool(wx.ID_UNDO, False)

        if self.count == 4:
            self.toolbar.EnableTool(wx.ID_REDO, True)

    def OnRedo(self, event):
        if self.count < 5 and self.count >= 1:
            self.count = self.count + 1

        if self.count == 5:
            self.toolbar.EnableTool(wx.ID_REDO, False)

        if self.count == 2:
            self.toolbar.EnableTool(wx.ID_UNDO, True)

    def OnExit(self, event):
        self.Close()

app = wx.App()
EnableDisable(None, -1, 'enable disable')
app.MainLoop()

V našem příkladu obsahuje lišta tři tlačítka. Jedno pro ukončení aplikace, zbylá dvě tlačítka se snaží simulovat funkci Zpět a Vpřed.

self.toolbar.EnableTool(wx.ID_REDO, False)
self.toolbar.AddSeparator()

Na začátku předchozího kódu je tlačítko Zpět zablokováno (disabled). Udělali jsme to zavoláním metody EnableTool(). Na druhém řádku vytváříme separátor. Ten má podobnou funkci jako v menu - odděluje skupiny tlačítka. Separátor se vytváří pomocí metody AddSeparator().

Zdroj: http://zetcode.com/wxpython/menustoolbars/

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor studuje na FIT ČVUT a je šéfredaktorem portálu Matematika pro každého.
Web    

Nové články

Obrázek ke článku NEWTON Media prohledá 200  milionů mediálních zpráv během sekund díky Cisco UCS

NEWTON Media prohledá 200 milionů mediálních zpráv během sekund díky Cisco UCS

Česká společnost NEWTON Media provozuje největší archiv mediálních zpráv ve střední a východní Evropě. Mezi její zákazníky patří například ministerstva, evropské instituce nebo komerční firmy z nejrůznějších oborů. NEWTON Media rozesílá svým zákazníkům každý den monitoring médií podle nastavených klíčových slov a nabízí online službu, kde lze vyhledat mediální výstupy v plném znění od roku 1996.

Reklama
Reklama
Obrázek ke článku Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Delphi 10.1.2 (Berlin Update 2) – na co se můžeme těšit

Touto roční dobou, kdy je zem pokrytá barevným listím a prsty křehnou v mrazivých ránech, se obvykle těšíme na zbrusu novou verzi RAD Studia. Letos si však ale budeme muset počkat na Godzillu a Linux až do jara. Vezměme tedy za vděk alespoň updatem 2 a jelikož dle vyjádření pánů z Embarcadero se budou nové věci objevovat průběžně, pojďme se na to tedy podívat.

Obrázek ke článku Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Konference: Moderní datová centra pro byznys dneška se koná už 24. 11.

Stále rostoucí zájem o cloudové služby i maximální důraz na pružnost, spolehlivost a bezpečnost IT vedou k výrazným inovacím v datových centrech. V infrastruktuře datových center hraje stále významnější roli software a stále častěji se lze setkat s hybridními přístupy k jejich budování i provozu.

Obrázek ke článku Konference: Mobilní technologie mají velký potenciál pro byznys

Konference: Mobilní technologie mají velký potenciál pro byznys

Firmy by se podle analytiků společnosti Gartner měly  rychle přizpůsobit skutečnosti, že mobilní technologie už zdaleka nejsou horkou novinkou, ale standardní součástí byznysu. I přesto - nebo možná právě proto - tu nabízejí velký potenciál. Kde tedy jsou ty největší příležitosti? I tomu se bude věnovat již čtvrtý ročník úspěšné konference Mobilní řešení pro business.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý