Simples Beispiel und wxGlade Gebrauch

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Hallo liebe Leute

nachdem ich mich an Tkinter versucht habe und ich feststellen musste, dass Tkinter sich nicht für mein Projekt eignet, bin ich auf wxPython umgestiegen.

Ich habe dabei zwei kleine Probleme:

1. In keinem der Tutorials war ein übersichtliches Codebeispiel, dass nur aus einem Text, einem Eingabefeld und einem Button, der mit der Eingabe was anstellt, besteht. Die meisten Beispiele fahren gleich mit allen Möglichkeiten (Radiobuttons etc) auf, was mich wegen der OOP-orientiertheit von wxGlade überfordert. Speziell das Event-Handling verwirrt mich, da ich nicht begreife, wie man an den Inhalt eines Eingabefeldes kommt und diesen dann nach irgendwo weitergibt. Hat vielleicht jemand von euch solch ein kleines simples Code-Beispiel, dass er posten könnte?

2. Wenn ich eine GUI mit wxGlade bastle, ist die Verwirrung komplett, da Glade-Code mit import wx andere Code-Beispiele aber mit anderen Anweisungen arbeiten (u.a. from wxPython.wx import *). Was ist der Unterschied? Was ist "besser"? Und wie kriege ich Glade-Code zum laufen? Soweit ich das begriffen habe, fehlt die Erzeugung eines Objekts und die Übergabe an den Mainloop(). Aber was genau?

Den Code, der mir Glade generiert hat:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF8 -*-
# generated by wxGlade 0.3.5.1 on Wed Jul 13 13:45:56 2005

import wx

class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MainFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.MainPanel = wx.Panel(self, -1)
        self.static_line_1 = wx.StaticLine(self, -1)
        self.label_9 = wx.StaticText(self.MainPanel, -1, "Test")
        
        # Menu Bar
        self.MainFrame_menubar = wx.MenuBar()
        self.SetMenuBar(self.MainFrame_menubar)
        self.File = wx.Menu()
        self.Open = wx.MenuItem(self.File, 1011, "Open", "Open File", wx.ITEM_NORMAL)
        self.File.AppendItem(self.Open)
        self.Close = wx.MenuItem(self.File, 1012, "Close", "Close File", wx.ITEM_NORMAL)
        self.File.AppendItem(self.Close)
        self.Exit = wx.MenuItem(self.File, 1013, "Exit", "Exit programm", wx.ITEM_NORMAL)
        self.File.AppendItem(self.Exit)
        self.MainFrame_menubar.Append(self.File, "File")
        self.Help = wx.Menu()
        self.Documentation = wx.MenuItem(self.Help, 1021, "Documentation", "See Documentation", wx.ITEM_NORMAL)
        self.Help.AppendItem(self.Documentation)
        self.About = wx.MenuItem(self.Help, 1022, "About", "About HeatCalc", wx.ITEM_NORMAL)
        self.Help.AppendItem(self.About)
        self.MainFrame_menubar.Append(self.Help, "Help")
        # Menu Bar end
        self.MainFrame_statusbar = self.CreateStatusBar(1, 0)

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

    def __set_properties(self):
        # begin wxGlade: MainFrame.__set_properties
        self.SetTitle("HeatCalc Version 00.1")
        self.SetSize((1592, 1101))
        self.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, 0, ""))
        self.MainFrame_statusbar.SetStatusWidths([-1])
        # statusbar fields
        MainFrame_statusbar_fields = ["Comments"]
        for i in range(len(MainFrame_statusbar_fields)):
            self.MainFrame_statusbar.SetStatusText(MainFrame_statusbar_fields[i], i)
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MainFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_MainWindow = wx.BoxSizer(wx.VERTICAL)
        sizer_1.Add(self.static_line_1, 0, wx.EXPAND, 0)
        sizer_MainWindow.Add(self.label_9, 0, 0, 0)
        self.MainPanel.SetAutoLayout(True)
        self.MainPanel.SetSizer(sizer_MainWindow)
        sizer_MainWindow.Fit(self.MainPanel)
        sizer_MainWindow.SetSizeHints(self.MainPanel)
        sizer_1.Add(self.MainPanel, 1, wx.EXPAND, 0)
        self.SetAutoLayout(True)
        self.SetSizer(sizer_1)
        self.Layout()
        self.Centre()
        # end wxGlade

# end of class MainFrame


class MainWindow(wx.Frame):
    def __init__(self, *args, **kwds):
        # content of this block not found: did you rename this class?
        pass

    def __set_properties(self):
        # content of this block not found: did you rename this class?
        pass

    def __do_layout(self):
        # content of this block not found: did you rename this class?
        pass

# end of class MainWindow
Für die Hilfe danke ich im voraus...
querdenker
User
Beiträge: 424
Registriert: Montag 28. Juli 2003, 16:19
Wohnort: /dev/reality

Ich habe hier einfach mal einen test geposted:?

Code: Alles auswählen

!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-
# generated by wxGlade 0.4cvs on Wed Jul 13 13:41:46 2005

import wx

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.label_5 = wx.StaticText(self, -1, u"Büro", style=wx.ALIGN_CENTRE)
        self.choice_4 = wx.Choice(self, -1, choices=[])
        self.button_3 = wx.Button(self, -1, "hole Daten...")
        self.label_1 = wx.StaticText(self, -1, u"Sachverständiger")
        self.label_2 = wx.StaticText(self, -1, "GA-Nr")
        self.label_3 = wx.StaticText(self, -1, "KFZ-Kennz")
        self.choice_1 = wx.Choice(self, -1, choices=[])
        self.choice_2 = wx.Choice(self, -1, choices=[])
        self.choice_3 = wx.Choice(self, -1, choices=[])
        self.panel_1 = wx.Panel(self, -1)
        self.panel_2 = wx.Panel(self, -1)
        self.panel_3 = wx.Panel(self, -1)
        self.panel_4 = wx.Panel(self, -1)
        self.panel_5 = wx.Panel(self, -1)
        self.panel_6 = wx.Panel(self, -1)
        self.panel_7 = wx.Panel(self, -1)
        self.panel_8 = wx.Panel(self, -1)
        self.panel_9 = wx.Panel(self, -1)
        self.button_1 = wx.Button(self, -1, "<")
        self.label_4 = wx.StaticText(self, -1, "Anzahl Gefundene: ", style=wx.ALIGN_CENTRE)
        self.button_2 = wx.Button(self, -1, ">")

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.get_office_data, self.button_3)
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame_1")
        self.choice_4.SetSelection(0)
        self.choice_1.SetSelection(0)
        self.choice_2.SetSelection(0)
        self.choice_3.SetSelection(0)
        self.panel_1.SetMinSize((100,100))
        self.panel_2.SetMinSize((100,100))
        self.panel_3.SetMinSize((100,100))
        self.panel_4.SetMinSize((100,100))
        self.panel_5.SetMinSize((100, 100))
        self.panel_6.SetMinSize((100,100))
        self.panel_7.SetMinSize((100,100))
        self.panel_8.SetMinSize((100,100))
        self.panel_9.SetMinSize((100,100))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_1 = wx.FlexGridSizer(7, 3, 0, 0)
        grid_sizer_1.Add(self.label_5, 0, wx.BOTTOM|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 2)
        grid_sizer_1.Add(self.choice_4, 0, wx.BOTTOM|wx.ADJUST_MINSIZE, 2)
        grid_sizer_1.Add(self.button_3, 0, wx.BOTTOM|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 2)
        grid_sizer_1.Add(self.label_1, 0, wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.label_2, 0, wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.label_3, 0, wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.choice_1, 0, wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.choice_2, 0, wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.choice_3, 0, wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.panel_1, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_2, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_3, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_4, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_5, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_6, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_7, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_8, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.panel_9, 1, wx.ALL|wx.EXPAND, 2)
        grid_sizer_1.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.label_4, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.Add(self.button_2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
        grid_sizer_1.AddGrowableRow(7)
        grid_sizer_1.AddGrowableRow(8)
        grid_sizer_1.AddGrowableRow(9)
        grid_sizer_1.AddGrowableCol(0)
        grid_sizer_1.AddGrowableCol(1)
        grid_sizer_1.AddGrowableCol(2)
        sizer_1.Add(grid_sizer_1, 1, wx.EXPAND, 0)
        self.SetAutoLayout(True)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        sizer_1.SetSizeHints(self)
        self.Layout()
        # end wxGlade

    def get_office_data(self, event): # wxGlade: MyFrame.<event_handler>
        print "Event handler `get_office_data' not implemented"
        event.Skip()

# end of class MyFrame


if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    frame_1 = MyFrame(None, -1, "")
    app.SetTopWindow(frame_1)
    frame_1.Show()
    app.MainLoop()



mfg, querdenker
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Erzeugt eine Fehlermedlung, danke aber für den Eintrag.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Clython hat geschrieben:2. Wenn ich eine GUI mit wxGlade bastle, ist die Verwirrung komplett, da Glade-Code mit import wx andere Code-Beispiele aber mit anderen Anweisungen arbeiten (u.a. from wxPython.wx import *). Was ist der Unterschied? Was ist "besser"?
Meinst du den unterschied zwischen import wx und from wxPython.wx import *.

Es geht darum, dass wxPython in Version 2.4 auch endlich kapiert hat das *-Importe nicht besonders elegant sind, vor allem wenn es bessere Lösungen gibt. So wurden vorher alle Module in deinen Namespace reinkopiert und du hattest neben deinen Variablen auch mehrere hundert Variablen wie wxApp. Ab 2.4 geht auch import wx, was alle Variablen in den wx-Namensraum importiert (also wird aus wxApp wx.App). Letzteres ist inzwischen auch die von den Entwicklern favorisiete Methode.

Mehr zu ModulImporten gibts im Wiki.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Clython
User
Beiträge: 151
Registriert: Samstag 21. August 2004, 13:58
Wohnort: Schweiz, BE-2500

Danke Leonidas eine Frage hat sich inzwischen geklärt. Aber nachdem ich die wxPYthon demo Beispiele (speziell die Beispielcodes) angeschaut habe, bin ich nur noch verwirrter. Und ich bin der Lösung meines Problems keinen Schritt weiter. Wie komme ich an den Wert eines wxTextCtrl-Widegets?
In dem Code den ich gesehen habe, hat es immer zwei Events:

Code: Alles auswählen

EVT_TEXT(self, ID_EDITNAME_FIELD, self.EvtText)
EVT_CHAR(self.editname, self.EvtChar)
#und die Funktionen dazu
def EvtText(self, e):
    self.editname.AppendText('EvtText: %s\n' % event.GetString())
def EvtChar(self, e):
    self.editname.AppendText('EvtChar: %d\n' % event.GetKeyCode())
    event.Skip()
Aber was tun die Dinger genau? Ich hab den Code 1 zu 1 übernommen, aber die GUI stürtzt ab, wenn ich was ins Feld eingeben will!

Ganzer Text

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

from wxPython.wx import *

#ID Definitionen
ID_DOC=201
ID_ABOUT=202
ID_CLOSE=102
ID_EXIT=103
ID_OPEN=101
ID_BUTTON_QUAD=301
ID_EDITNAME_FIELD=401
# Definition der restlichen Variablen
dialog_inhalt="""Blabla"""
class MainWindow(wxFrame):
    def __init__(self,parent,id,title):
        wxFrame.__init__(self,parent,wxID_ANY, title, size = ( 200,100),
                                     style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
        
        #Fenster                             
        self.quote = wxStaticText(self, -1, "Zu Quadrierende Zahl:",wxPoint(20, 30))
        self.editname = wxTextCtrl(self, ID_EDITNAME_FIELD, "", wxPoint(20, 60), wxSize(140,-1))
        self.button = wxButton(self, ID_BUTTON_QUAD, "Quadrieren", wxPoint(20, 95))
        
        #Creating Statusbar in the bottom of the window
        self.CreateStatusBar()
        
        # Setting up the File menu.
        filemenu= wxMenu()
        filemenu.Append(ID_OPEN, "&Open"," Open a File")
        filemenu.AppendSeparator()
        filemenu.Append(ID_CLOSE, "&Close"," Close a File")
        filemenu.AppendSeparator()
        filemenu.Append(ID_EXIT,"E&xit"," Terminate the program")
        
        # Setting up the Help menu.
        helpmenu= wxMenu()
        helpmenu.Append(ID_DOC, "&Documentation"," Have a look a the Documentation")
        helpmenu.AppendSeparator()
        helpmenu.Append(ID_ABOUT,"&About"," Displays Programm Infos and Credits")
        
        # Creating the menubar.
        menuBar = wxMenuBar()
        menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.
        menuBar.Append(helpmenu,"&Help") # Adding the "filemenu" to the MenuBar
        self.SetMenuBar(menuBar)  # Adding the MenuBar to the Frame content.

        #Events
        #In File Menu
        EVT_MENU(self, ID_EXIT, self.OnExit)   # attach the menu-event ID_EXIT to the
        #In Help Menu
        EVT_MENU(self, ID_ABOUT, self.OnAbout) # attach the menu-event ID_ABOUT to the
        #In Window
        EVT_TEXT(self, ID_EDITNAME_FIELD, self.EvtText)
        EVT_CHAR(self.editname, self.EvtChar)
        EVT_MENU(self, ID_BUTTON_QUAD, self.OnQuad)
                                                           
        self.Show(true)
        
    def OnAbout(self,e):
        d= wxMessageDialog( self, dialog_inhalt,"About HeatCalc", wxOK) # Create a message dialog box
        d.ShowModal() # Shows it
        d.Destroy() # finally destroy it when finished.
    def OnExit(self,e):
        self.Close(true)  # Close the frame.
        
    def OnQuad(self, editname_content):
        result = editname_content * editname_content
        self.result_out = wxStaticText(self, -1, result,wxPoint(20, 300))
        
    
    def EvtText(self, e):
        self.editname.AppendText('EvtText: %s\n' % event.GetString())
    def EvtChar(self, e):
        self.editname.AppendText('EvtChar: %d\n' % event.GetKeyCode())
        event.Skip()
        
app = wxPySimpleApp()
frame = MainWindow(None, -1, "HeatCalc")
app.MainLoop()
Was mache ich falsch?
Antworten