Verwendung verschiedener Sizer

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Benutzeravatar
Toni83
User
Beiträge: 125
Registriert: Donnerstag 28. Juli 2005, 10:53

Hallo,

Habe extreme Probleme mit Sizern! Habe im Forum und auch in der wxPython Demo die Beispiele durchgemacht, aber keine brauchbare Lösung für mein Problem gefunden:
Oberfläche:

Code: Alles auswählen

--------------------------------|
|                       1              |
|-------------------------------|
|   2   |                              |
|        |                              |
|------|               4              |
|        |                              |
|   3   |                              |
|-------------------------------|
Feld 1 ist ein Bitmap, dass bei Vergrößerung des Frames durch den Benutzer das Feld nur in horizontaler Richtung größer werden und das Bild mittig zentriert werden soll.
Feld 2 ist ein Notebook, dass trotz der möglichen Größenänderung des Frames die gleiche Größe behalten soll.
Feld 3 ist ein TextCtrl, dass sich nur Vertikal vergrößern soll und Feld 4 (HTML-Window) soll sich nur nach rechts und nach unten hin vergrößern.

Habe schon versucht ein Panel herzunehmen, mehrere durch SplitWindow und die Widgets darauf zu positionieren, Grid Sizer, BoxSizer,... egal was ich mache, immer ist bei einer Lösung irgendetwas nicht richtig. Vor allem werden bei meinen Lösungen nur die Panels größer, nícht aber die darauf positionierten Elemente.
Ich werde es zwar noch weiter versuchen, aber ich benötige da echt Hilfe bei dem komplexen Problem, da ich im Moment echt nicht weiß, was ich noch probieren soll! Danke im Voraus!

Gruß,
Toni

Edit (Leonidas): Skizze in Code-Tags gesetzt.
Benutzeravatar
Toni83
User
Beiträge: 125
Registriert: Donnerstag 28. Juli 2005, 10:53

Sorry, total zerrupft.
Wie kann man hier Bilder einfügen?
Habe mal provisorisch Leerzeichen durch Bindestrich ersetzt (einfach die Striche wegdenken)

Code: Alles auswählen

|++++++++++++++|
|-----------1-------------|
|++++++++++++++|
|---2---|-----------------|
|++++|-------4---------|
|---3---|-----------------|
|++++++++++++++|
Edit (Leonidas): Skizze in Code-Tags gesetzt.
BlackJack

Das "Bild" hättest Du in einem Editor mit einer "Monospace"-Schriftart "malen" und dann als <code> hier einfügen können. So hängt das auch immer noch von der jeweiligen Proportionalschriftart ab, wie gut die ASCII-Grafik aussieht.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Et voila.

P.S.: Du kannst auch deine alten Postings editieren und das Bild anpassen, dazu musst du nicht jedes mal ein neues Posting schreiben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Toni83 hat geschrieben:Ich werde es zwar noch weiter versuchen, aber ich benötige da echt Hilfe bei dem komplexen Problem
Hallo Toni!

Z.B. so:

Code: Alles auswählen

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

import wx
import wx.html

wx.SetDefaultPyEncoding("iso-8859-15")


class TopPanel(wx.Panel):
    
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("yellow")
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(vbox)
        
        bmp = wx.ArtProvider_GetBitmap(wx.ART_HARDDISK)
        sb_logo = wx.StaticBitmap(self, bitmap = bmp)
        vbox.Add(sb_logo, 0, wx.ALIGN_CENTER | wx.ALL, 10)
    
    
class LeftTopNotebook(wx.Notebook):
    
    def __init__(self, parent):
        wx.Notebook.__init__(self, parent)
        
        notebook_panel_1 = wx.Panel(self)
        notebook_panel_1.SetBackgroundColour("green")
        self.AddPage(notebook_panel_1, "Panel 1")
        
        notebook_panel_2 = wx.Panel(self)
        notebook_panel_2.SetBackgroundColour("blue")
        self.AddPage(notebook_panel_2, "Panel 2")


class LeftBottomTextCtrl(wx.TextCtrl):
    
    def __init__(self, parent):
        wx.TextCtrl.__init__(self, parent, style = wx.TE_MULTILINE)
        self.ChangeValue(u"Uuuuaaaahhhh")


class LeftSplitter(wx.SplitterWindow):
    
    def __init__(self, parent):
        wx.SplitterWindow.__init__(self, parent)
        
        nb_left_top = LeftTopNotebook(self)
        txt_left_bottom = LeftBottomTextCtrl(self)
        
        self.SplitHorizontally(nb_left_top, txt_left_bottom)


class HtmlContent(wx.html.HtmlWindow):
    
    def __init__(self, parent):
        wx.html.HtmlWindow.__init__(self, parent)
        
        html = (
            u"<center><h1>Hallo Welt</h1></center>"
            u"<p>Servus aus Tirol</p>"
        )
        self.SetPage(html)


class MyFrame(wx.Frame):
    
    def __init__(
        self, parent = None, title = "Example", size = wx.Size(550, 420)
    ):
        wx.Frame.__init__(self, parent, -1, title, size = size)
        
        main_panel = wx.Panel(self)
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        main_panel.SetSizer(vbox)
        
        # TopPanel
        top_panel = TopPanel(main_panel)
        vbox.Add(top_panel, 0, wx.EXPAND)
        
        # SplitterWindow
        main_splitter = wx.SplitterWindow(main_panel)
        vbox.Add(main_splitter, 1, wx.EXPAND | wx.ALL, 5)
        
        left_splitter = LeftSplitter(main_splitter)
        html_content = HtmlContent(main_splitter)
        
        main_splitter.SplitVertically(left_splitter, html_content)


def main():
    """Testing"""
    app = wx.PySimpleApp()
    f = MyFrame()
    f.Center()
    f.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
Toni83
User
Beiträge: 125
Registriert: Donnerstag 28. Juli 2005, 10:53

Danke an alle!
Spitzenantwort, Gerold! Vielen Dank! Nachdem ich jetzt wieder Zeit hab, werd ich das Beispiel von Dir mal gleich durchgehen.
Benutzeravatar
Toni83
User
Beiträge: 125
Registriert: Donnerstag 28. Juli 2005, 10:53

Habe dann doch noch folgendes Problem:
Wenn ich beispielsweise das Code Snippet vom Gerold für die GUI in ein Skript GUI.py übernehme und die zugehörigen Events (von Buttons,...) in einem anderen Skript Events.py gespeichert habe, wie kann ich dann von Events.py aus, die Inhalte von z.B. ListCtrls (wx.SetItem) in GUI.py verändern?
Oder wie kann ich von einem Event aus Events.py bspw. das im Beispiel vom Gerold genannte HTML-Window, durch ein Editor Window (wx.lib.editor) mit den selben Eigenschaften ersetzen, sodass von Events.py zwischen der Anzeige HTML-Window und Editor-Window gewechselt werden kann? Muss ich nicht vorher durch .Destroy() das HTML-Fenster zerstören und auf den Splitter main_splitter das Editor-Fenster positionieren? Funktioniert leider nicht.. Hab jetzt echt n´ Brett vorm Kopf.

Gruß,
Toni
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Toni83 hat geschrieben:Wenn ich beispielsweise das Code Snippet vom Gerold für die GUI in ein Skript GUI.py übernehme und die zugehörigen Events (von Buttons,...) in einem anderen Skript Events.py gespeichert habe, wie kann ich dann von Events.py aus, die Inhalte von z.B. ListCtrls (wx.SetItem) in GUI.py verändern?
Hallo Toni!

Ich muss einzeln antworten, sonst komme ich durcheinander.

Was könnte es für einen Grund geben, die Events von der GUI zu trennen?

Es gibt zwei gute Möglichkeiten, Events weiterzuleiten.
Die eine Möglichkeit ist ein wenig aufwändiger, aber dafür trennt sie die einzelnen Teile sehr gut voneinander ab. Man erstellt benutzerdefinierte Events und kümmert sich nicht darum, was ein "Parent" damit macht.

Die andere Möglichkeit: Man kümmert sich in den einzelnen Objekten nicht um die Events und überlässt alles dem Parent. Die Trennung ist dadurch nicht wirklich gegeben und bei größeren Projekten kommt man damit gerne mal ins Strudeln.

Ich versuche das mal in zwei Beispielen zu verdeutlichen.

Beispiel mit gekapselten Events: :)
http://www.python-forum.de/post-98407.html

Beispiel ohne gekapselten Events: :|
http://www.python-forum.de/post-98409.html#98409

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Toni83 hat geschrieben:das im Beispiel vom Gerold genannte HTML-Window, durch ein Editor Window (wx.lib.editor) mit den selben Eigenschaften ersetzen, sodass von Events.py zwischen der Anzeige HTML-Window und Editor-Window gewechselt werden kann?
Hallo Toni!

Die Kinder des SplitterWindow verändern ist keine gute Idee. Aber du könntest in den Splitter ein einfaches Panel legen. In das Panel legst du je nach Bedarf entweder das HtmlWindow oder den Editor rein. So verändert sich das SplitterWindow nicht. Die Änderungen passieren im Panel.

Vor dem Ändern muss das alte Widget aus dem Sizer genommen werden. Dann kannst du das alte Widget zerstören. Danach wird das neue Widget erstellt und in den Sizer gelegt. Siehe: http://www.python-forum.de/topic-10536.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
Toni83
User
Beiträge: 125
Registriert: Donnerstag 28. Juli 2005, 10:53

Wow, das war ja schnell! Ist ja der Wahnsinn! Wie kannst Du den so schnell eine so detaillierte Antwort schreiben?...
Was ich mir dabei gedacht habe die Events von der GUI zu trennen:
Durch einen Event, z.B. Button wird eine Funktion aufgerufen (Beispielname: func). Ich wollte aber kein Klassenmodul self.func erstellen, da bei Zunahme der aktiven Widgets auf der GUI das zugehörige Python-Skript ziemlich unübersichtlich wird. Also wollte ich die Funktionen in ein eigenes Skript Event.py übernehmen. Die zugehörigen Events wollte ich gleich mitnehmen, da wenn ich bspw. aus einem Event aus GUI.py heraus self.func (in Event.py) starte und danach ein anderes Event aus GUI.py mit der Funktion self.func2 (in Event.py) starte, die Variablen aus self.func danach in self.func2 nicht mehr vorhanden sind. Dies kann ich bis jetzt nur umgehen, wenn ich die Variablen aus self.func in Event.py als globale Variablen setze, erst dann kann ich diese in self.func2 verwenden! Wobei ich mir mittlerweile nicht mehr sicher bin, ob eine Weiterleitung von Events aus GUI.py in Event.py da eine Verbesserung bringen würde...
Antworten