Sizer aktualisieren?

Plattformunabhängige GUIs mit wxWidgets.
Antworten
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Hallo,

hab folgendes Problem.
Ich hab mit wxPython ein Infofenster (wx.Dialog) erstellt, also es erscheint, wenn man in einer GUI auf ein Button klickt.
Dieses wx.Dialog ist natürlich mit Sizern aufgebaut und ich habe einem Sizer von den vielen eine Liste von Links hinzugefügt.
Wenn man auf einen solchen Link klickt, geht ein Menüfenster auf und man kann den Namen des Links ändern. Soweit so gut, allerdings ist der neue Name des Links nicht direkt sichtbar, sondern erst, wenn ich das Infofenster erst schliesse und wieder öffne....
Nun meine Frage, kann man das ganze irgendwie aktualisieren, ohne dass man das Fenster schliessen/öffnen muss?
sea-live
User
Beiträge: 440
Registriert: Montag 18. Februar 2008, 12:24
Wohnort: RP

probier es mal mit .Restore()
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

geht leider nicht.
Es kommt dann eine Fehlermeldung, dass der BoxSizer das Attribut Restore() nicht kennt.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Code wäre hilfreich.
MfG
HWK
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

blubber hat geschrieben:Nun meine Frage, kann man das ganze irgendwie aktualisieren, ohne dass man das Fenster schliessen/öffnen muss?
Hallo blubber!

Normalerweise sollte ein ``self.Layout()`` genügen. ``Layout()`` muss für den Container ausgeführt werden, an den der Sizer gebunden wurde. Es könnte auch ein ``Fit()`` und ein nachträgliches ``Layout()`` zum Ziel führen.

Genaueres kann man aber ohne ein funktionierendes Quellcode-Beispiel nicht sagen. Denn wir wissen ja nicht, wie bei dir die Widgets und Sizer zueinander in Beziehung stehen.

Im Normalfall, gibt man die Anweisung, sich an neue Verhältnisse anzupassen, nicht an den Sizer, sondern an den Container an den der Sizer gebunden wurde.

mfg
Gerold
:-)
Zuletzt geändert von gerold am Montag 3. November 2008, 08:59, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

OK, also hier dann Codeausschnitte.
Wenn man innerhalb meiner GUI auf einen Button klickt, wird ein Objekt dieser Klasse angelegt:

Code: Alles auswählen

class SequenceInfo(wx.Dialog):
Innerhalb der Initialisierung der Klasse leg ich unter anderem diese Sizer an:

Code: Alles auswählen

        # Haupt-Sizer 
        vbox_main = wx.BoxSizer(wx.VERTICAL) 
        self.SetSizer(vbox_main) 
        
        # Sizer für den oberen Bereich (horizontal) 
        hbox_content = wx.BoxSizer(wx.HORIZONTAL) 
        vbox_main.Add(hbox_content, 0, wx.EXPAND | wx.ALL, 5) 
        
        # Sizer für Parameter
        self.sizer_parameter = wx.BoxSizer(wx.VERTICAL)
        vbox_main.Add(self.sizer_parameter, 0, wx.LEFT|wx.ADJUST_MINSIZE, 73)
So, und der Parameter-Sizer wird nun innerhalb der Initialisierung mit Daten gefüllt. Zur Erklärung:
Bei "params" handelt es sich um ein Dictionary, welches als Schlüssel-Wertepaare eben Parameter mit Daten enthält. Meine Schleife durchläuft das Dictionary und stellt innerhalb des Sizers die einzelnen Paare als Links dar, und zwar immer

ParameterX = WertX
ParameterY = WertY
usw.

Code: Alles auswählen

        testdaten = ""
        for item in params:        
            testdaten = hl.HyperLinkCtrl(self, wx.ID_ANY, str(item)+" = "+str(params[item]), URL="http://www.google.com")
            self.sizer_parameter.Add(testdaten, 0, wx.RIGHT, 15)

            testdaten.SetColours("BLUE", "BLUE", "BLUE")
            testdaten.EnableRollover(True)
            testdaten.SetUnderlines(False, False, True)
            testdaten.UpdateLink()   
            
            testdaten.Bind(hl.EVT_HYPERLINK_LEFT, lambda event, obj=str(item), obj2=str(params[item]): self.EditParam(event, obj, obj2))
            
            testdaten.SetToolTip(wx.ToolTip("Parameterwert bearbeiten")) 
            testdaten.AutoBrowse(False) 

Wenn man nun auf einen solchen Link klickt, wird ja die Funktion EditParam() aufgerufen. Diese öffnet mir einen TextEntryDialog, welcher als Defaultwert den aktuellen Parameterwert enthält:

Code: Alles auswählen

        dlg = wx.TextEntryDialog(self, 'Neuen Parameterwert eingeben:',parameter)
        dlg.SetValue(wert)
So, un nun das Problem, weil bis hierher funktioniert alles einwandfrei! Wenn ich nun den Parameterwert ändere und in die ursprüngliche Dictionary schreibe, dann seh ich den neuen Wert nicht direkt. Sprich, ich änder ParameterX mit WertX auf WertZ.
Nun wird nicht direkt

ParameterX = WertZ

als Link angezeigt, sondern erst, wenn ich mein Dialogfenster (welches ich von der GUI aus geöffnet hatte) wieder schliesse und neu öffne. Weil erst dann wird ja im Grunde wieder meine Schleife durchlaufen, welche die Dictionary durchsucht und die Links zum Sizer hinzufügt...

Hoffe, das Problem ist jetzt klarer und jemand hat einen Tip für mich.

Gruß
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Also als eigenen Lösungsvorschlag würde ich quasi meine Schleife in eine Funktion auslagern und diese jedes mal aufrufen, wenn ich einen Parameterwert änder. Das Problem ist nur, dann müsste ich davor jedesmal den Inhalt von dem Sizer leeren (weil da ja die aktuellen Links drinstehen) und ich weis net, wie das gehen soll oder ob das überhaupt geht.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo blubber!

Code: Alles auswählen

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

import wx
import wx.lib.hyperlink

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


class MyDialog(wx.Dialog):
    
    def __init__(self, parent = None, title = "Example"):
        wx.Dialog.__init__(self, parent, -1, title)
        vbox_main = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(vbox_main)
        self.data = {
            "Parameter 1": "Wert 1",
            "Parameter 2": "Wert 2",
            "Parameter 3": "Wert 3"
        }
        for key, value in self.data.items():
            label = key + " = " + value
            new_link = wx.lib.hyperlink.HyperLinkCtrl(self, label = label)
            new_link.key = key
            vbox_main.Add(new_link, 0, wx.ALL, 10)
            new_link.AutoBrowse(False)
            new_link.Bind(
                wx.lib.hyperlink.EVT_HYPERLINK_LEFT, self.on_hyperlink_left
            )
        self.Fit()
    
    
    def on_hyperlink_left(self, event):
        hl_ctrl = event.GetEventObject()
        
        message = u"Geben Sie den neuen Wert ein."
        caption = u"Wert ändern"
        old_value = self.data[hl_ctrl.key]
        edit_dialog = wx.TextEntryDialog(self, message, caption, old_value)
        if edit_dialog.ShowModal() == wx.ID_OK:
            new_value = edit_dialog.GetValue()
            self.data[hl_ctrl.key] = new_value
            label = hl_ctrl.key + " = " + new_value
            hl_ctrl.SetLabel(label)
        edit_dialog.Destroy()
        
        self.Fit()
        self.Center()


def main():
    """Testing"""
    app = wx.PySimpleApp()
    diag = MyDialog()
    diag.Center()
    diag.ShowModal()
    print repr(diag.data)
    diag.Destroy()


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.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Vielen Dank, gerold.
Habe zunächst nur Deinen Code ausprobiert und das ist genau das, was ich gemeint habe! Nun setzt ich das noch bei mir um, danke nochmals!
Antworten