ich beschäftige mich derzeit mit Python im Allgemeinen und wx.Python als GUI-Framework. Bis jetzt konnte ich relativ viele Fragen durch googeln selbst klären, doch nun stoße ich langsam an meine Grenzen und hoffe auf ein paar hilfreiche Hinweise von erfahrenen Nutzern.
Zum besseren Verständnis habe ich ein „Minimalbeispiel“, einen Screenshot und ein Klassendiagramm angefügt. (Leider darf ich als neuer Nutzer offensichtlich keine Dateien anhängen, so dass ich erstmal nur das Minimalbeispiel unten angehängt habe.)
Die Anwendung soll einen Startup-Bildschirm haben und nach Aufforderung durch den User (z.Z Klick auf Datei=>Neu) in den „Produktivmodus“ umschalten. Der Screenshot zeigt, wie ich mir diese Ansicht im Wesentlichen vorstelle. Leider gibt es noch ein paar Punkte, die mir nicht so gut gefallen und für die ich bis jetzt noch keine Lösung gefunden habe.
- Durch die Verschachtelung der verschiedenen Elemente scheinen bestimmte Elemente (Splitter, Notebook, …) eigene Rahmen zu zeichnen. Da ich Default-Einstellungen verwende ist dies sicher seitens des GUI-Frameworks korrekt. Wie verhindere ich diese Rahmendarstellung, so dass sich z.B. die beiden geschachtelten Splitter für den Nutzer wie ein MultiSplitterWindow darstellen? (wx.NO_BORDER etc. habe ich erfolglos probiert, so dass ich einen Denkfehler meinerseits vermute.)
Anm. 1: Ich verwende bewusst kein MultiSplitterWindow, da dieses keine Gravity zur Verfügung stellt.
Anm. 2: Den Style NB_MULTILINE kann ich nicht verwenden, da die Anwendung auf Windows und Linux laufen soll. - Zum Thema MultiSplitterWindow, habe ich unabhängig vom Minimalbeispiel eine Frage: Ist es möglich diesem mitzugeben, dass es bei Größenänderungen die einzelnen Elemente proportional zur Ausgangsgröße skaliert? (Ich habe es nur geschafft, dass alle Elemente die gleiche Größe beibehalten haben und das rechteste bzw. unterste Element skaliert wurde.)
- Auf der obersten Strukturebene habe ich das Fenster in zwei Bereiche untergliedert. Der linke Bereich enthält zwei Überblicksspalten mit entsprechender Überschrift. Verkleinert man einen oder beide Überblicksbereiche derart, dass die jeweiligen Überschriften nicht mehr vollständig dargestellt werden können, verschwinden diese – im Gegensatz zu den Einträgen – komplett. Was habe ich falsch gemacht, da ich eigentlich möchte, dass die Überschriften, wie die Einträge auch, einfach nur abgeschnitten werden sollen?
- Die Skalierung der Elemente scheint im Minimalbeispiel bis auf die CSheets zu funktionieren. Welchen Fehler habe ich gemacht, dass die CSheets im Notebook erst an den zur Verfügung stehenden Platz angepasst werden, wenn der Sash des vertikalen Splitters bewegt wird?
- Bewegt man eben diesen Sash, krallen sich die CSheets den zur Verfügung stehenden Platz vollständig. Was müsste ich ergänzen, um dafür zu sorgen, dass die CSheets nur den von ihnen benötigten Platz einnehmen und der Rest in der Hintergrundfarbe dargestellt wird?
Vielen Danke.
Sören
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: latin-1 -*-
'''
Created on 14.01.2016
@author: Sören
'''
import wx
from wx.lib import sheet
'''
Hierarchie:
wx.Frame (Fenster)
wx.Panel (Startbildschirm)
wx.Panel (Hauptbildschirm)
Multislpitter horizontal => Da für Multisplitter keine Gravityfunktion existiert, wurden geschachtelte SplitterWindows verwendet
- Links(1/6 Bildschirmbreite): Konten mit Überschrift
- Mitte(1/6 Bildschirmbreite): Kategorien mit Überschrift
- Rechts (2/3 Bildschirmbreite: Doppeltes Notebook
wx.notebook (Jahre)
wx.notebook (Monate)
SplitterWindow vertikal
- Oben (1/2 Bildschirmhöhe): Transfer mit Überschrift
- Unten (1/2 Bildschirmhöhe): Buchungen mit Überschrift
'''
class Panel_Startup(wx.Panel):
def __init__(self, parent, color):
"""Constructor"""
wx.Panel.__init__(self, parent)
self.SetBackgroundColour(color)
class Panel_Entry(wx.Panel):
def __init__(self, parent, name, value):
wx.Panel.__init__(self, parent)
text = wx.StaticText(self, -1, " " + str(name) + ":", size=(-1,16))
text.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
value = wx.StaticText(self, -1, str(value), pos=(100,-1),size=(-1,16))
value.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
class Panel_Overview_Category(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
heading = wx.StaticText(self, -1, " Kategorien:", size=(-1,25))
heading.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
example1 = Panel_Entry(self, "Kategorie 1", 100)
example2 = Panel_Entry(self, "Kategorie 2", 20)
example3 = Panel_Entry(self, "Kategorie 3", 1)
sizer.Add(heading, 0, wx.EXPAND)
sizer.Add(example1, 0, wx.EXPAND)
sizer.Add(example2, 0, wx.EXPAND)
sizer.Add(example3, 0, wx.EXPAND)
self.SetSizer(sizer)
class Panel_Overview_Account(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
heading = wx.StaticText(self, -1, " Konten:", size=(-1,25))
heading.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
example1 = Panel_Entry(self, "Konto A", 0)
example2 = Panel_Entry(self, "Konto B", 50)
example3 = Panel_Entry(self, "Konto C", 1000)
sizer.Add(heading, 0, wx.EXPAND)
sizer.Add(example1, 0, wx.EXPAND)
sizer.Add(example2, 0, wx.EXPAND)
sizer.Add(example3, 0, wx.EXPAND)
self.SetSizer(sizer)
class Transfer_Sheet(sheet.CSheet):
def __init__(self, parent):
sheet.CSheet.__init__(self, parent)
self.row = self.col = 0
self.SetNumberRows(20)
self.SetNumberCols(5)
self.SetColLabelValue(0, "Datum")
self.SetColLabelValue(1, "Betrag")
self.SetColLabelValue(2, "Quelle")
self.SetColLabelValue(3, "Ziel")
self.SetColLabelValue(4, "Bemerkung")
self.SetColSize(4,200)
class Booking_Sheet(sheet.CSheet):
def __init__(self, parent):
sheet.CSheet.__init__(self, parent)
self.row = self.col = 0
self.SetNumberRows(20)
self.SetNumberCols(5)
self.SetColLabelValue(0, "Datum")
self.SetColLabelValue(1, "Betrag")
self.SetColLabelValue(2, "Kategorie")
self.SetColLabelValue(3, "Konto")
self.SetColLabelValue(4, "Bemerkung")
self.SetColSize(4,200)
class Panel_Box_Transfer(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
heading = wx.StaticText(self, -1, " Transfers", size=(-1,25))
heading.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
table = Transfer_Sheet(self)
sizer.Add(heading, 0, wx.EXPAND)
sizer.Add(table, 1, wx.EXPAND)
self.SetSizer(sizer)
class Panel_Box_Booking(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
heading = wx.StaticText(self, -1, " Buchungen", size=(-1,25))
heading.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
table = Booking_Sheet(self)
sizer.Add(heading, 0, wx.EXPAND)
sizer.Add(table, 1, wx.EXPAND)
self.SetSizer(sizer)
class Panel_Splitter_Entry(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.HORIZONTAL)
splitter = wx.SplitterWindow(self)
splitter.SetMinimumPaneSize(wx.DisplaySize()[1]/8)
panel_transfer = Panel_Box_Transfer(splitter)
panel_booking = Panel_Box_Booking(splitter)
splitter.SplitHorizontally(panel_transfer, panel_booking)
splitter.SetSashGravity(0.5)
sizer.Add(splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
class Panel_Notebook_Month(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
notebook = wx.Notebook(self, -1)
sheet_jan = Panel_Splitter_Entry(notebook)
sheet_feb = Panel_Splitter_Entry(notebook)
sheet_mrz = Panel_Splitter_Entry(notebook)
sheet_apr = Panel_Splitter_Entry(notebook)
sheet_mai = Panel_Splitter_Entry(notebook)
sheet_jun = Panel_Splitter_Entry(notebook)
sheet_jul = Panel_Splitter_Entry(notebook)
sheet_aug = Panel_Splitter_Entry(notebook)
sheet_sep = Panel_Splitter_Entry(notebook)
sheet_okt = Panel_Splitter_Entry(notebook)
sheet_nov = Panel_Splitter_Entry(notebook)
sheet_dez = Panel_Splitter_Entry(notebook)
sheet_jan.SetFocus()
notebook.AddPage(sheet_jan, 'Jan.')
notebook.AddPage(sheet_feb, 'Feb.')
notebook.AddPage(sheet_mrz, 'März')
notebook.AddPage(sheet_apr, 'April')
notebook.AddPage(sheet_mai, 'Mai')
notebook.AddPage(sheet_jun, 'Juni')
notebook.AddPage(sheet_jul, 'Juli')
notebook.AddPage(sheet_aug, 'Aug.')
notebook.AddPage(sheet_sep, 'Sept.')
notebook.AddPage(sheet_okt, 'Okt.')
notebook.AddPage(sheet_nov, 'Nov.')
notebook.AddPage(sheet_dez, 'Dez.')
sizer.Add(notebook, 1, wx.EXPAND)
self.SetSizer(sizer)
class Panel_Notebook(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
notebook = wx.Notebook(self, -1)
sheet1 = Panel_Notebook_Month(notebook)
sheet2 = Panel_Notebook_Month(notebook)
sheet3 = Panel_Notebook_Month(notebook)
sheet1.SetFocus()
notebook.AddPage(sheet1, '2014')
notebook.AddPage(sheet2, '2015')
notebook.AddPage(sheet3, '2016')
sizer.Add(notebook, 1, wx.EXPAND)
self.SetSizer(sizer)
class Panel_Main(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
main_splitter = wx.SplitterWindow(self)
main_splitter.SetMinimumPaneSize(wx.DisplaySize()[0]/24)
overview_splitter = wx.SplitterWindow(main_splitter)
overview_splitter.SetMinimumPaneSize(wx.DisplaySize()[0]/48)
panel_accounts = Panel_Overview_Account(overview_splitter)
panel_categories = Panel_Overview_Category(overview_splitter)
panel_notebook = Panel_Notebook(main_splitter)
overview_splitter.SplitVertically(panel_accounts, panel_categories)
overview_splitter.SetSashGravity(0.5)
main_splitter.SplitVertically(overview_splitter, panel_notebook, -(2*parent.GetSize()[0]/3)) # Dritter Parameter funktioniert bei positiven Werten nicht sauber.
main_splitter.SetSashGravity(0.5)
sizer.Add(main_splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, -1, title, size = (wx.DisplaySize()[0]/2, wx.DisplaySize()[1]/2), pos = (0,0))
# Menü- und Statusbar
menubar = wx.MenuBar()
menu_file = wx.Menu() # Für Datei
newfilemenu = menu_file.Append(wx.ID_NEW, "Neu"," Anlegen einer neuen Abrechnung")
self.Bind(wx.EVT_MENU, self.Click_New, newfilemenu)
menubar.Append(menu_file, "Datei") # Adding the "menu_file" to the MenuBar
self.SetMenuBar(menubar)
self.CreateStatusBar()
# Bildschirme
self.panel_startup = Panel_Startup(self, 'red')
self.panel_main = Panel_Main(self)
self.panel_main.Hide()
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel_startup, 1, wx.EXPAND)
sizer.Add(self.panel_main, 1, wx.EXPAND)
self.SetSizer(sizer)
self.SetMinSize((640, 320))
def Click_New(self, event):
self.panel_startup.Hide()
self.panel_main.Show()
self.Layout()
event.Skip()
app = wx.App()
myframe = MyFrame(None,-1,"GUI-Design Testwindow")
myframe.Show(True)
app.MainLoop()