Grafik unter wxPython

Plattformunabhängige GUIs mit wxWidgets.
Antworten
jocsch
User
Beiträge: 31
Registriert: Freitag 4. April 2003, 13:09
Wohnort: Egloffstein (Hundshaupten)

Hallo, alle!
Wie erzeugt man denn unter wxPython Vektorgrafik (ich stelle mir was ähnliches vor, wie unter Tkinter das Canvas-Widget) -
kann mir eine(r) helfen?!

Guten Rutsch und danke soweit

jocsch
Christopy
User
Beiträge: 131
Registriert: Montag 15. Dezember 2003, 22:39

Keine Ahnung wie es unter Tkinter geht, aber mit wxWindows geht sowas mit Device Contexten (wxDC).
Als Beispiel ein abgeleitetes Fenster auf das ein Kreis und eine Ellipse gemalt wird:

Code: Alles auswählen

class MyWindow(wxWindow):
    
    def __init__(self, *args, **kwds):
        wxWindow.__init__(self, *args, **kwds)
        self.SetBackgroundColour(wxColour(255, 255, 255))
        self.SetSize((400, 400))        
        EVT_PAINT(self, self.OnPaint)

    def OnPaint( self, event ):        
        dc = wxPaintDC(self)
        dc.DrawCircle( 100, 100, 50)
        dc.DrawEllipse( 150, 150, 50, 100 )

Wird in der Methode OnPaint gezeichnet, muss wxPaintDC benutzt werden. Für Zeichnungen, die ausserhalb von OnPaint gemacht werden, muss wxClientDC benutzt werden. Beide sind von wxDC abgeleitet und erben alle Zeichenmethoden von wxDC.

Edit (Leonidas): Code in Python-Tags gesetzt.
redeye
User
Beiträge: 12
Registriert: Mittwoch 11. Mai 2005, 13:45

hi

aber wie stellt man es an, dass die classe dc kennt. bei mir bringt er einen fehler, dass dc nicht bekannt ist.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Ui, da hast Du aber einen alten Thread ausgegraben ...
Poste doch mal Deinen Code, dann kann man sehen, wo der Fehler liegt.

Gruß,
Christian
redeye
User
Beiträge: 12
Registriert: Mittwoch 11. Mai 2005, 13:45

hi

hab es gerade geschafft, also bei mir muss ich kein clientDC erstellen, der PaintDC reicht. hier mal der Code, hab da noch ein Problem. Und zwar wenn ich jetzt was zeichne(per Menubutton) und ich das Fenster verschiebe, verschwindet das gezeichnete immer. Aber ich weiss nicht warum.

Code: Alles auswählen

import wx
import wx.xrc as xrc
import os
import random
import types
import pickle

#define Makros for XML Resources
XRCID = xrc.XRCID
XRCCTRL = xrc.XRCCTRL
EVT_MENU = wx.EVT_MENU
EVT_BUTTON = wx.EVT_BUTTON
EVT_TOGGLEBUTTON = wx.EVT_TOGGLEBUTTON
EVT_TEXT = wx.EVT_TEXT
               
class Frame_Game(wx.Frame):    
    def __init__(self,parent,aha):
       
        wx.Frame.__init__(self,parent,-1,"gehen",pos=(50,50),size=(1024,768))
        #Load the sourcefile
        res = xrc.XmlResource("dialog.xrc") 
        #Create the panel from the resource data
        self.panel = res.LoadPanel(self,"Haupt")
        #Import the menu bar from xml
        menu = res.LoadMenuBarOnFrame(self,"MENUBAR")
        #Provide a statusbar to display information on menuitems
        statusbar = self.CreateStatusBar(style = wx.ST_SIZEGRIP)
        #Set standard text
        self.SetStatusText("drawing in a panel")
        #Define Event Handlers for this class/resource
        EVT_MENU(self,XRCID("Exit"),self.TimeToLeave)
        EVT_MENU(self,XRCID("Neu"),self.doPaint)
        EVT_MENU(self,XRCID("alueg"),self.OnAlueg)
        EVT_MENU(self,XRCID("versteck"),self.OnAlueg)
        wx.EVT_PAINT(self,self.OnPaint)
        self.DR = None
     
    def OnPaint(self,evt): 
        dc = wx.PaintDC(self.panel) 
        self.DR = dc
##        dc.DrawLine(50,50,150,150) 
##        dc.DrawCircle(250,150,50) 
##        dc.DrawEllipse(100,100,50,100)
      
    def doPaint(self,evt):
        self.DR.BeginDrawing()
        self.DR.DrawLine(50,50,150,150) 
        self.DR.EndDrawing() 
         
    def TimeToLeave(self,evt):
        """Event handler for the close button."""
        self.Close()
          
    def OnAlueg(self,evt):
        self.DR.DrawText('ach so',50,50)
        
    def OnHighscore(self,evt):
        wx.MessageBox('haha','highscore')
        
    def OnAbout(self,evt):
        wx.MessageBox("LeoYatzee 0.1a\n","About")
    
class App_game_main(wx.App):
    def OnInit(self):
        frame = Frame_Game(None, "drawbox")
        #Do not allow to resize the windows
##        frame.SetWindowStyle(wx.DEFAULT_FRAME_STYLE& ~(wx.RESIZE_BORDER |
##            wx.RESIZE_BOX | wx.MAXIMIZE_BOX))
        self.SetTopWindow(frame)
        frame.Show(True)
        return True
            
app = App_game_main(redirect=True)
app.MainLoop()

    

   
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Hallo,

kannst Du auch die dazugehörige XRC Datei hereinposten?
Sonst kann man nicht viel damit anfangen :)
redeye
User
Beiträge: 12
Registriert: Mittwoch 11. Mai 2005, 13:45

hier die xrc datei und sorry hehe

Code: Alles auswählen

<?xml version="1.0" ?>
<resource>
  <object class="wxMenuBar" name="MENUBAR">
    <object class="wxMenu" name="Datei">
      <label>Datei</label>
      <object class="wxMenuItem" name="Neu">
        <label>zeichne</label>
      </object>
      <object class="wxMenuItem" name="Exit">
        <label>Exit</label>
      </object>
    </object>
    <object class="wxMenu" name="sonst">
      <label>sonst</label>
      <object class="wxMenuItem" name="alueg">
        <label>alueg</label>
      </object>
      <object class="wxMenuItem" name="versteck">
        <label>versteck</label>
      </object>
    </object>
  </object>
  <object class="wxPanel" name="Haupt">
    <size>1024,768</size>
    <style></style>
    <enabled>1</enabled>
  </object>
</resource>
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

redeye hat geschrieben:hier die xrc datei und sorry hehe
Sehr gut.

So ein Glücksfall, haben wir gleich gehabt :wink:
Stutzig hat mich gemacht (print statment in OnPaint), dass es
andauernd aufgerufen wurde.

Nachdem ich ein evt.Skip() am Schluess in OnPaint aufgerufen habe,
war das weg, und das gezeichnete wird auch wieder richtig aktualisiert.
redeye
User
Beiträge: 12
Registriert: Mittwoch 11. Mai 2005, 13:45

hmh.... ist komisch..
Naja sehr gut danke.

also einfach evt.Skip() am Schluss einfügen und dann klappt es auch???
cool, ich probiere es gleich aus.. vielen Dank

edit: aber wieso wird es denn die ganze Zeit aufgerufen???
In der Doku steht nichts davon..
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

redeye hat geschrieben:hmh.... ist komisch..
Naja sehr gut danke.

also einfach evt.Skip() am Schluss einfügen und dann klappt es auch???
cool, ich probiere es gleich aus.. vielen Dank

edit: aber wieso wird es denn die ganze Zeit aufgerufen???
In der Doku steht nichts davon..
Ja eigenartig.

Habe die Frage einmal in die wxpy user mailing list gestellt.
redeye
User
Beiträge: 12
Registriert: Mittwoch 11. Mai 2005, 13:45

ehm, jetzt hab ich grad erfahren, dass ich dies mit OGL realisieren soll. Hat da jemand erfahrung mit? Weil ich finde so gut wie nichts im Internet und in der Doku steht leider auch nichts...

In der Demo hab ich ein Beispiel dazu gefunden, jedoch frage ich mich:
Muss ich dem Canvas das Handle vom Panel geben oder lädt der dies automatisch.

bringt dies wirklich einen Strich auf das Panel?:

Code: Alles auswählen

        line = ogl.LineShape()
        line.SetCanvas(self)
        line.SetPen(wx.BLACK_PEN)
        line.SetBrush(wx.BLACK_BRUSH)
        line.AddArrow(ogl.ARROW_ARROW)
        line.MakeLineControlPoints(2)
        line.Show(True)
Edit (Leonidas): Code in Python-Tags gesetzt.
redeye
User
Beiträge: 12
Registriert: Mittwoch 11. Mai 2005, 13:45

Code: Alles auswählen

import wx
import wx.lib.ogl as ogl

class AppFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__( self,
                          None, -1, "Demo",
                          size=(300,200),
                          style=wx.DEFAULT_FRAME_STYLE )
        sizer = wx.BoxSizer( wx.VERTICAL )
        # put stuff into sizer

        canvas = ogl.ShapeCanvas( self )
        sizer.Add( canvas, 1, wx.GROW )

        canvas.SetBackgroundColour( "LIGHT BLUE" ) #

        diagram = ogl.Diagram()
        canvas.SetDiagram( diagram )
        diagram.SetCanvas( canvas )

        shape = ogl.CircleShape( 20.0 )            #
        shape.SetX( 25.0 )                         #
        shape.SetY( 25.0 )                         #
        canvas.AddShape( shape )             #
        canvas.AddShape( shape )
        diagram.ShowAll( 1 )                       #

        # apply sizer
        self.SetSizer(sizer)
        self.SetAutoLayout(1)
        self.Show(1)



app = wx.PySimpleApp()
ogl.OGLInitialize()
frame = AppFrame()
app.MainLoop()
Edit (Leonidas): Code in Python-Tags gesetzt.
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Ja eigenartig.

Habe die Frage einmal in die wxpy user mailing list gestellt.
Jetzt weiss ich es.

Für das Archiv:

Hatte in der Doku übersehen, dass beim EVT_PAINT immer
dc = wx.PaintDC(self) kreiert werden muss.

"""
Note that In a paint event handler, the application must always create a wxPaintDC object, even if you do not use it.
"""


BTW: mit OGL kenne ich mich nicht aus.
Olliminator

Habe in der Docu gelesen dass man nicht Bilder grösser als 64 pixel verwenden soll!? Aber in den Demos sind auch Beispiel mit grösseren Bildern und ich habe bis jetzt auch keine Probleme in meiner GUI gehabt.
Weiss da einer näheres?
Benutze immernoch Windows.
Antworten