2 und mehr Eingabeelemente setzen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

Hallo,

wenn ich in meinem Programmierbeispiel oben in der Menüleiste auf "File" und dann auf "About" klicke, so sehe ich 1 Spinner-Element. Aber wie kann ich anstatt einem Element, zwei oder mehr solcher Elemente in meinem Frame platzieren?

So weit bin ich schon (das Spinner-Element wird im unteren Teil initialisiert):

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import wx

class MainWindow(wx.Frame):

    def __init__(self, parent = None, id = -1, title = "Small Editor"):
        # Init
        wx.Frame.__init__(
            self, parent, id, title, size = (400,200),
            style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE
        )

        # TextCtrl
        self.control = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)

        # StatusBar
        self.CreateStatusBar()

        # Filemenu
        filemenu = wx.Menu()

        # Filemenu - About
        menuitem = filemenu.Append(-1, "&About", "Information about this program")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuitem) # Hier wird der Event-Handler angegeben

        # Filemenu - Separator
        filemenu.AppendSeparator()

        # Filemenu - Exit
        menuitem = filemenu.Append(-1, "E&xit", "Terminate the program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuitem) # Hier wird der Event-Handler angegeben

        # Menubar
        menubar = wx.MenuBar()
        menubar.Append(filemenu,"&File")
        self.SetMenuBar(menubar)

        # Show
        self.Show(True)


    def OnAbout(self,event):
		#sets new text
		#self.control.SetValue("New Text")
		self.control.Hide();

                # 1 Spinner-Element
		self.control = wx.SpinCtrl(self, -1, "", (40,40), (90,-1))
		self.control.SetRange(1,100)
		self.control.SetValue(10)


    def OnExit(self,event):
        self.Close(True)  # Close the frame.


app = wx.PySimpleApp()
frame = MainWindow()
app.MainLoop()

# Zerstören der Objekte, damit dieses Beispiel
# im IDLE nicht nur einmal funktioniert.
del frame
del app
HAND
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
BlackJack

@pe: Ich weiss nicht ob ich die Frage richtig verstehe!? Indem Du halt mehrere Widgets erzeugst und nicht nur eines. Wo genau liegt das Problem?

Wenn diese mehreren Spinner anstelle des einen Texteingabefeldes erscheinen sollen, dann würde ich die in einem `Panel` zusammenfassen, damit Du da wirklich nur ein Widget austauschen musst.

Das alte `control` nur zu verstecken ist nicht so sinnvoll, denn wenn Du den Namen neu bindest, kommst Du da ja eh nicht mehr dran. Dann kannst Du's auch gleich zerstören.

Die Kommentare sind hoffentlich nur in der Lernphase da. Vieles davon könnte von Captain Obvious sein und bringt keinen Mehrwert beim lesen.

Man sollte keine Programme an die Macken einer bestimmten IDE anpassen. Wenn Du den Code am Ende nicht auf Modulebene sondern in einer Funktion stehen hast, dann erledigt sich das mit dem ``del``, weil die lokalen Namen nach Ende der Funktion ja nicht mehr existieren.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Ich würde mir zb einmal das Demo (mit der möglichkeit, den democode zu ändern) einmal ansehen. Auch das http://wiki.wxpython.org/AnotherTutorial ist gut geeignet, einen schnellen Überblick zu bekommen. Überhaupt die ganze wxPy Wiki.
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

BlackJack hat geschrieben:@pe: Ich weiss nicht ob ich die Frage richtig verstehe!? Indem Du halt mehrere Widgets erzeugst und nicht nur eines. Wo genau liegt das Problem?
Habe es vorhin so probiert und es ist wirklich so einfach. Dachte nicht, dass ich es einfach nur erzeugen und die Position angeben muss. Danke für den Hinweis.
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
BlackJack

@pe: Mit Position angeben meinst Du jetzt hoffentlich keine absoluten Positionen in Pixeln!? Für's Layout verwendet man besser Sizer. Sonst sieht die GUI nur bei Dir gut aus, und bei anderen entweder einfach nur "komisch" oder sogar unbenutzbar.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

BlackJack hat geschrieben:@pe: Mit Position angeben meinst Du jetzt hoffentlich keine absoluten Positionen in Pixeln!? Für's Layout verwendet man besser Sizer. Sonst sieht die GUI nur bei Dir gut aus, und bei anderen entweder einfach nur "komisch" oder sogar unbenutzbar.
Auch wichtig, wenn der Anwender die Dialoge resizen möchte. Dann sieht es wirklich nicht gut aus, wenn die Elemente links oben beisammen sind, und rechts unten dann ein grauer Bereich unbenützt bleibt. ;)
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

Also ich habe meine beiden Elemente folgendermaßen definiert:

Code: Alles auswählen

	
                self.control = wx.SpinCtrl(self, -1, "", (40,40), (90,-1))
		self.control.SetRange(1,100)
		self.control.SetValue(10)
		self.controlTwo = wx.SpinCtrl(self, -1, "", (80,80), (90,-1))
		self.controlTwo.SetRange(1,100) 
		self.controlTwo.SetValue(10)
Wie müsste ich die Elemente positionieren, damit sie nicht absolut ausgerichtet sind, sondern so wie ihr empfiehlt?
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
BlackJack

@pe: Du müsstest sie halt mit einem Sizer verwalten. Zum Beispiel einen `BoxSizer`.
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

Jetzt habe ich es mit BoxSizer versucht. Allerdings sehe ich dann oben links im Fenster nureinen sehr kleinen Teil eines Eingabeelements:
Bild.

Der Code:

Code: Alles auswählen

		panel = wx.Panel(self, -1)
		box = wx.BoxSizer(wx.HORIZONTAL)
		box.Add(wx.SpinCtrl(panel, -1, 'Spinner1'), 1, wx.ALL, 5)
		box.Add(wx.SpinCtrl(panel, -1, 'Spinner2'), 0, wx.EXPAND)
		box.Add(wx.SpinCtrl(panel, -1, 'Spinner3'), 0, wx.ALIGN_CENTER)
		panel.SetSizer(box)
		self.Centre()
Was mache ich hier falsch? Danke für Eure Aufmerksamkeit.

Nachtrag:
Ich habe mich übrigens an folgendem Beispiel orientiert: http://wiki.wxpython.org/AnotherTutorial#wx.BoxSizer.
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

An den Zeilen kann ich keinen Fehler erkennen. Kannst du mal ein minimales lauffaehiges Beispiel zeigen? Meistens ist sowas ein Hinweis darauf, dass irgendwelche Parent-Beziehungen nicht stimmen.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

Das ist jetzt das komplette Programm (ihr müsst nur oben in der Menüleiste "About" auswählen - anschließend wird die "OnAbout"-Methode ausgeführt und ihr seht was ich meine; hoffe das Beispiel ist minimal genug):

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import wx

class MainWindow(wx.Frame):

    def __init__(self, parent = None, id = -1, title = "Small Editor"):
        # Init
        wx.Frame.__init__(
            self, parent, id, title, size = (400,200),
            style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE
        )

        # TextCtrl
        self.control = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)

        # StatusBar
        self.CreateStatusBar()

        # Filemenu
        filemenu = wx.Menu()

        # Filemenu - About
        menuitem = filemenu.Append(-1, "&About", "Information about this program")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuitem) # Hier wird der Event-Handler angegeben

        # Filemenu - Separator
        filemenu.AppendSeparator()

        # Filemenu - Exit
        menuitem = filemenu.Append(-1, "E&xit", "Terminate the program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuitem) # Hier wird der Event-Handler angegeben

        # Menubar
        menubar = wx.MenuBar()
        menubar.Append(filemenu,"&File")
        self.SetMenuBar(menubar)

        # Show
        self.Show(True)


    def OnAbout(self,event):
		# sets new text
		#self.control.SetValue("New Text")
		self.control.Hide();
		# BoxSizer for proportional positioning
		panel = wx.Panel(self, -1)
		box = wx.BoxSizer(wx.HORIZONTAL)
		box.Add(wx.SpinCtrl(panel, -1, 'Spinner1'), 1, wx.ALL, 5)
		box.Add(wx.SpinCtrl(panel, -1, 'Spinner2'), 0, wx.EXPAND)
		box.Add(wx.SpinCtrl(panel, -1, 'Spinner3'), 0, wx.ALIGN_CENTER)
		panel.SetSizer(box)
		self.Centre()

    def OnExit(self,event):
        self.Close(True)  # Close the frame.


app = wx.PySimpleApp()
frame = MainWindow()
app.MainLoop()
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

vor dem self.Centre einfügen

Code: Alles auswählen

panel.SetSizer(box)
panel.Fit() #das einfügen
self.Centre()
oder die Kurzversion
statt SetSizer SetSizerAndFit() verwnden.
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

Wo steht das alles denn im WxPython Wiki? Ich finde mich da nicht gut zurecht. Könnt ihr mir denn Teile des Wikis empfehlen, die ihr praktisch nutzt?
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

pe hat geschrieben:Wo steht das alles denn im WxPython Wiki? Ich finde mich da nicht gut zurecht. Könnt ihr mir denn Teile des Wikis empfehlen, die ihr praktisch nutzt?
Steht doch auf How to learn wxPython:
Use the wxWidgets documentation
Das Leben ist wie ein Tennisball.
Antworten