Buttons in wx.Dialog nicht dargestellt [gelöst]

Plattformunabhängige GUIs mit wxWidgets.
Antworten
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

Hi,

komisches Problem, ich finde einfach keine Lösung:
[update]: Lösung unten kommentiert eingefügt ( '# FIX')!

Code: Alles auswählen

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


import wx

class dlgStartTimer(wx.Dialog):
    '''Show a dialog box to start the timer'''
    def __init__(self, parent):

        wx.Dialog.__init__( self, parent, 100, 'aktion starten', size=(250, 190))

        panel = wx.Panel(self, -1)
        vbox = wx.BoxSizer(wx.VERTICAL)

        label = wx.StaticText(panel, -1, 
                               'Waehle eine Aktion\noder gib eine neue ein'
                              )
        line = wx.StaticText(panel, -1, 
                               '--------------------'
                              )
        vbox.Add((-1, 10))
        vbox.Add(label, 0) 
        vbox.Add((-1, 10))
        self.comboBox = wx.ComboBox(panel, -1, value='Combobox', choices=[
           'eins','zwei','drei'], style= wx.CB_SORT | wx.CB_DROPDOWN )
        self.comboBox.SetSelection(0)

        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        hbox1.Add(self.comboBox, 0, wx.ALL, 1)
        vbox.Add(hbox1, 0)
        vbox.Add((-1, 10))

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)

        okButton = wx.Button(self, -1, 'Ok', size=(50, 25))
# FIX ----------------------^^^ hier muss panel stehen statt self
        okButton.Bind(wx.EVT_BUTTON, self.OnOk)
        okButton.SetDefault()

        closeButton = wx.Button(self, -1, 'Abbrechen', size=(50, 25))
# FIX ------------------------------------^^^ hier auch
        closeButton.Bind(wx.EVT_BUTTON, self.OnExit)
        
        hbox2.Add(okButton, 1, wx.ALL, 1)
        hbox2.Add(closeButton, 1, wx.ALL, 1)
        #hbox2.Add(line, 0, wx.ALL, 1)

        vbox.Add(hbox2, 0, wx.EXPAND | wx.ALL, 1)
# ------^^^^^ trotzdem wird hbox2 (bei mir) nicht dargestellt, bzw. die Buttons sind nicht zu sehen
        vbox.Add((-1, 10))
        vbox.Add(line, 0) 
# ------^^^^^ diese Linie kann ich aber wieder sehen...

        panel.SetSizer(vbox)
        #panel.Layout()
        panel.Fit()
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

        self.comboBox.SetFocus()

    def OnExit(self, event):
        self.action = 'closed'
        self.Close()


    def OnOk(self, event):
        self.action = 'ok'
        self.Close()

    def OnKeyDown(self, event):
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_ESCAPE:
            self.Close()
        event.Skip()

myApp = wx.PySimpleApp(0)
myFrame = dlgStartTimer(None)
myFrame.ShowModal()
myFrame.Destroy()


myApp.SetTopWindow(myFrame)
myFrame.Show()
myApp.MainLoop()
Weiss jemand, woran es hängt?

Vielen Dank,
Sven
Zuletzt geändert von svenXY am Donnerstag 15. Juli 2010, 15:09, insgesamt 2-mal geändert.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

IMO kannst du nicht direkt den zweiten Sizer hinzufuegen, sondern musst stattdessen ein Panel kreieren, auf dem du dann SetSizer(hbox2) aufrufst. Dieses Panel kannst du dann der vbox hinzufuegen.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

Rebecca hat geschrieben:IMO kannst du nicht direkt den zweiten Sizer hinzufuegen, sondern musst stattdessen ein Panel kreieren, auf dem du dann SetSizer(hbox2) aufrufst. Dieses Panel kannst du dann der vbox hinzufuegen.
nee, ich glaube, das ist nicht richtig.

http://www.zetcode.com/wxpython/layout/
wx.BoxSizer
This sizer enables us to put several widgets into a row or a column. We can put another sizer into an existing sizer. This way we can create very complex layouts.
Damit sollte man in einen BoxSizer jegliche andere Widgets reinsetzen können, ohne jedesmal ein extra panel zu brauchen...
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Ja, aber ein Sizer ist kein Widget. Alle Widgets haben Window als Oberklasse, Sizer nicht. Das merkt man schon daran, dass du beim Sizer beim Erstellen kein Parent angeben musst, welches fuer ein Widget festlegt, wo es reingezeichnet wird...
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
svenXY
User
Beiträge: 27
Registriert: Dienstag 16. Juni 2009, 10:36
Kontaktdaten:

Nein. Das Beispiel hier tut genau das, was ich haben möchte und es gibt trotzdem nur ein panel:

Code: Alles auswählen

import wx

class SelectAction(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title, size=(300, 150))
        ### 1! Panel
        panel = wx.Panel(self, -1)

        ### 1 Boxsizer als Top-Sizer, darin andere Elemente, 
        #### unter anderem auch andere BoxSizer
        vbox = wx.BoxSizer(wx.VERTICAL)

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        st2 = wx.StaticText(panel, -1, 'Waehle eine Aktion')

        hbox2.Add(st2, 0)
        vbox.Add(hbox2, 0, wx.LEFT | wx.TOP, 10)

        vbox.Add((-1, 10))

        hbox3 = wx.BoxSizer(wx.HORIZONTAL)
        self.comboBox = wx.ComboBox(panel, -1, value='', 
                                    choices=['eins','zwei','drei'], 
                                    style= wx.CB_SORT | wx.CB_DROPDOWN )

        hbox3.Add(self.comboBox, 1, wx.EXPAND | wx.LEFT | wx.TOP, 10)
        vbox.Add(hbox3, 0)

        vbox.Add((-1, 25))

        hbox5 = wx.BoxSizer(wx.HORIZONTAL)
        btn1 = wx.Button(panel, -1, 'Ok', size=(70, 30))
        hbox5.Add(btn1, 0)

        btn2 = wx.Button(panel, -1, 'Close', size=(70, 30))
        hbox5.Add(btn2, 0, wx.LEFT | wx.BOTTOM , 5)
        vbox.Add(hbox5, 0, wx.CENTRE | wx.RIGHT, 10)

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


myApp = wx.PySimpleApp(0)
myFrame = SelectAction(None, -1, 'test')
myFrame.ShowModal()
print myFrame.comboBox.GetValue()
myFrame.Destroy()


myApp.SetTopWindow(myFrame)
myFrame.Show()
myApp.MainLoop()

Was jetzt genau der Unterschied zum anderen Beispiel war muss ich selbst erst nochmal überprüfen (das ist jeweils angepasster Code aus Referenzimplementationen.

Gruss,
Sven
BlackJack

@Rebecca: Sizer kann man direkt an die `Add()`-Methode von anderen Sizern übergeben. In der C++-API ist die Methode auch entsprechend überladen.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Okay, wieder was gelernt. :)
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Antworten