DrawLine

Plattformunabhängige GUIs mit wxWidgets.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

tomate hat geschrieben:
gerold hat geschrieben:

Code: Alles auswählen

    def on_panel_paint(self, event = None):
        dc = wx.PaintDC(self.panel)
Wie kann ich es hinkriegen, dass on_panel_paint erst aufgerufen wird, wenn ich einen Button in der Toolbar anklicke?
Hallo tomate!

Bin jetzt nicht sicher ob das weiterhilft, aber wenn du deine Paint-Methode erst beim dem Klicken des Buttons dem Event zuweist und danach ein Refresh() machst, wuerde das auch gehen. Ist es vielleicht was du willst?

Code: Alles auswählen

import wx

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.SetClientSize((640, 480))
        self.panel = wx.Panel(self)

        self.btn = wx.Button(self.panel, -1, "CLICK!",
            pos=(270, 220),
            size=(100, 20)
        )
        #btn2 = wx.Button(self, -1, "CLICK!", pos=(200, 200))
        self.btn.Bind(wx.EVT_BUTTON, self.on_button)

    def on_button(self, evt):
        self.panel.Bind(wx.EVT_PAINT, self.on_paint)
        self.return_bmp(forced_refresh=True)
        self.panel.Refresh()

    def on_paint(self, evt):
        wx.BufferedPaintDC(self.panel, self.return_bmp())

    def return_bmp(self, forced_refresh=False):
        if forced_refresh or not hasattr(self, "_buffer"):
            self._buffer = wx.EmptyBitmap(*self.GetClientSize())
            
            # hab mal mein Fieldset als Beispiel missbraucht
            MARGIN = 10
            TXT = "Hallo Welt!"
            
            dc = wx.MemoryDC()
            dc.SelectObject(self._buffer)
            dc.Clear()
            
            w, h = dc.GetSizeTuple()
            
            TXTW = dc.GetTextExtent(TXT)[0] + MARGIN
            TXTH = dc.GetTextExtent(TXT)[1]
            
            lines = (
                (MARGIN, MARGIN, 3*MARGIN, MARGIN),
                (3*MARGIN+TXTW, MARGIN, w-MARGIN, MARGIN),
                (MARGIN, MARGIN, MARGIN, h-MARGIN),
                (w-MARGIN, MARGIN, w-MARGIN, h-MARGIN),
                (MARGIN, h-MARGIN, w-MARGIN+1, h-MARGIN)
            )
            dc.DrawLineList(lines)
            dc.DrawText(TXT, 3*MARGIN+MARGIN/2, MARGIN-TXTH/2)
            
            dc.SelectObject(wx.NullBitmap)
            
        return self._buffer
        
        
if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = Frame(None)
    frame.Show()
    
    app.MainLoop()
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Stranger
User
Beiträge: 4
Registriert: Sonntag 20. Januar 2008, 18:34

Danke. Jetzt funktioniert es bei mir auch.

Kannst du mir vielleicht noch einen Tipp geben, wie ich das ganze mit mehreren Methoden zum Zeichnen umsetzen könnte?
Sollte ich dann für jede eine eigene "on_paint"-Methode erstellen oder geht das auch eleganter?
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Sei kreativ! Bei einem Refresh() kannst du die komplette Bitmap neuzeichnen lassen... du koenntest einfach ne Liste von Bitmaps durchgehen, indem du nen Index-Zaehler durchgehst, beim klicken.
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Stranger
User
Beiträge: 4
Registriert: Sonntag 20. Januar 2008, 18:34

Leider haut das alles noch nicht so hin wie ich es möchte.

Meine Idee war, dass ich eine Methode hab, die grundsätzlich für das Zeichnen verantwortlich ist, wie bei dir:

Code: Alles auswählen

    def return_bmp(self, forced_refresh=False):
        if forced_refresh or not hasattr(self, "_buffer"): 
        ...
Zusätzlich gibt es dann die

Code: Alles auswählen

    
    def on_paint(self, evt):
        wx.BufferedPaintDC(self.panel, self.return_bmp())
Meine Idee war jetzt, dass ich unterschiedliche Buttons hab. Also:

Code: Alles auswählen

    def on_button_x(self, evt):
        self.panel.Bind(wx.EVT_PAINT, self.on_paint)
        self.return_bmp(x, forced_refresh=True)
        self.panel.Refresh()

    def on_button_y(self, evt):
        self.panel.Bind(wx.EVT_PAINT, self.on_paint)
        self.return_bmp(y, forced_refresh=True)
        self.panel.Refresh()
Meine Idee war jetzt, dass ich der "return_bmp" Methode noch einen weiteren Parameter übergebe, der bestimmt was gezeichnet wird.
Ist es möglich, dass ich aus der return_bmp abhängig von dem Parameter eine bestimmte Methode aufrufen, die etwas zeichnet und es dann an die return_bmp zurückliefert? Oder ist das eine schlechte Idee?

Sollte dann ungefähr so aussehen:

Code: Alles auswählen

    def return_bmp(self, parameter, forced_refresh=False):
        if forced_refresh or not hasattr(self, "_buffer"):
            self._buffer = wx.EmptyBitmap(*self.GetClientSize())
           
           
            dc = wx.MemoryDC()
            dc.SelectObject(self._buffer)
            dc.Clear()
           
            if parameter == x:
                dc = DrawSomething(dc)
            elif parameter == y:
                dc. = DrawSomething2(dc)
          

           
            dc.SelectObject(wx.NullBitmap)
           
        return self._buffer 
Könnte das irgendwie so gehen?

Danke
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Ja so koennte man das machen. Probier es doch einfach mal aus ;)
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Stranger
User
Beiträge: 4
Registriert: Sonntag 20. Januar 2008, 18:34

Leider klappt es irgendwie nicht.

In der return_bmp kann ich beispielsweise einen Rahmen zeichnen. Aber wenn ich dann aus der return_bmp eine Methode aufrufe, die etwas in den Rahmen zeichnen soll, funktioniert es leider nicht.


Die zusätzliche Methode sieht wie folgt aus:

Code: Alles auswählen

def DrawLines(self, dc):
    dc.SetPen(pen)
    dc.DrawLine(10, 10, 50, 50)
    
    return dc
Leider gibt es keine Fehlermeldung. Evtl ist das Problem, dass ich der on_paint den Parameter auch übergeben müsste?

Edit:
Lag an der on_paint Methode. Funktioniert jetzt.

Danke für deine Hilfe
Antworten