Hallo Norbert
Das ist kein Problem - ich bin froh wenn mich jemand auf grobe Schnitzer hinweist und mir Tipps geben kann... dafür gibt's ja das Forum
Ich bin anhand Deiner Tipps weiter gekommen und habe ein bisschen was verbessern können.
rufst du bei jedem Size-Event self.createDocIcon() auf. Deshalb werden bei dir auch jedesmal neue Widgets erzeugt.
Wird nun nur einmal aufgerufen, und beim Size-Event werden nur die jeweils neu positiniert - so wie es gedacht ist.
global: nicht verwenden, das ist böse und keine gute Idee! Übergib besser den DC beim Aufruf an deine Funktion als Argument. Kann es sein, das du dir nicht im Klaren darüber bist, dass man Funktionen Parameter als Argumente übergeben kann (und sollte!) sowie dass Funktionen Werte zurückgeben können? Wenn du davon Gebrauch machst, kannst du deinen Code besser kapseln und kommst *ohne* global aus.
So gelöst:
Code: Alles auswählen
def OnPaint(self, evt):
dc = wx.PaintDC(self.cPnl.timePnl)
self.drawMeds(dc)
def drawMeds(self, dc):
if self.data.curr_pat.connected:
for i in range(len(self.data.meds)):
#self.model.meds[i]['started']
s = math.ceil(self.data.calcDayRatio() * math.ceil(self.data.calcMedPos(i)[0]))
s = (self.data.xPnlSize - s - 20)
#if self.data.meds[]
l = math.ceil(self.data.calcDayRatio() * math.ceil(self.data.calcMedPos(i)[1]))
dc.SetPen(wx.Pen('grey', 5))
dc.DrawLine(s, ((i+1)*10)+20, s+l, ((i+1)*10)+20)
Refresh im Paint-Event? Das ist bestenfalls überflüssig und führt schlimmstenfalls zum Absturz.
Ebenfalls eliminiert.
wenn du ein lauffähiges Minimalbeispiel nicht oder nur unter Schwierigkeiten erstellen kannst, ist das ein deutlicher Hinweis, dass dein Code keine klaren Strukturen aufweist. Konkret heißt das, dein Code ist wie ein kompliziertes Uhrwerk, bei dem ein Rädchen ins andere greift. Weil jeder Teil von vielen anderen abhängt, ist es nicht mehr möglich, ein Teil zu isolieren, z.B. um es zu testen. Hier hilft eigentlich nur ein Redesign des Programms mit sauberer Trennung zwischen den einzelnen Komponenten.
Das "Problem" hierbei ist, dass ich nur mit zwei Dateien arbeiten kann, diese aber nur Teile einer grösseren Software sind. Ich kann zwar die Panels alleine testen, aber ohne die Daten der "Logik" kann ich leider nichts nachvollziehen.
Ist es ausserdem so (wie ich bereits im letzten Posting vermutet habe), dass du eigentlich ein Diagramm erstellen willst und die sog. "Dokumente" beschreiben eine Aktivität über einen bestimmte Zeitspanne, die du dann im Diagramm grafisch darstellen willst?
Wenn dem so ist, ist der ganze Umweg über die Dokumenten-Icons unnötig, du kannst direkt deine Linien in das Panel zeichnen (was du ja bereits versuchst) und dann anhand des Motion-Events auf die Mausaktivitäten reagieren.
Das hast Du richtig vermutet, allerdings sollen die Dokumente wirklich nur als Punkte erscheinen, und die sind nun auch so wie sie sein sollen. Allerdings möchte ich andere Aktivitäten (Einnahmedauer von Medikamenten) als Zeitspanne mit HIlfe von Linien zeichnen. Dort ist mir nicht klar, wie ich Events "holen" kann; also wenn ich z.B. mit der Maus über einer mit DrawLine gezeichneten Linie bin. Wäre Klasse wenn sowas auch funktionieren würde. Die Frage ist, an was ich welchen Event binden soll?
Dann habe ich noch weitere Fragen... sorry aber ich hoffe ich mache dann weniger Fehler... Ich habe eine Klasse mit meinen Berechnungen, welche von einer anderen erbt (nur der Konstruktor):
Code: Alles auswählen
class cTimelinePnl(wxgTimelinePnl.wxgTimelinePnl):
def __init__(self, *args, **kwargs):
wxgTimelinePnl.wxgTimelinePnl.__init__(self, *args, **kwargs)
self.__register_interests()
self.data = cTimelineData()
Die andere Klasse:
Code: Alles auswählen
import wx
class wxgTimelinePnl(wx.Panel):
def __init__(self, *args, **kwds):
kwds["style"] = wx.TAB_TRAVERSAL
wx.Panel.__init__(self, *args, **kwds)
self.vPnl = ViewPanel(self, -1, style=wx.SIMPLE_BORDER)
self.cPnl = ControlPanel(self, -1, style=wx.NO_BORDER)
self.vPnl.SetBackgroundColour(wx.Colour(0, 255, 0))
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(self.vPnl, 70, wx.EXPAND | wx.ALL, 10)
mainSizer.Add(self.cPnl, 30, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
self.SetSizer(mainSizer)
mainSizer.Fit(self)
class TimePnl(wx.Panel):
def __init__(self, *args, **kwds):
wx.Panel.__init__(self, *args, **kwds)
class ControlPanel(wx.Panel):
def __init__(self, *args, **kwds):
wx.Panel.__init__(self, *args, **kwds)
#self.model = self.Parent.model
self.data = gmTimelineWidgets()
self.x1 = 0
self.x2 = 0
self.rectDrawn = False
self.rectX = 0
self.rectW = 0
self.pnlSize = None
self.rectPnl = wx.Panel(self, -1)
self.timePnl = TimePnl(self, 1)
self.checkPnl = wx.Panel(self, -1)
self.rectPnl.SetBackgroundColour(wx.Colour(0, 127, 255))
self.timePnl.SetBackgroundColour(wx.Colour(255, 255, 255))
self.checkPnl.SetBackgroundColour(wx.Colour(255, 255, 133))
self.controlSizer = wx.BoxSizer(wx.VERTICAL)
self.controlSizer.Add(self.rectPnl, 10, wx.EXPAND, 0)
self.controlSizer.Add(self.timePnl, 80, wx.EXPAND, 0)
self.controlSizer.Add(self.checkPnl, 10, wx.EXPAND, 0)
self.bilderCb = wx.CheckBox(self.checkPnl, -1, "Bilder")
'''
self.videoCb = wx.CheckBox(self.checkPnl, -1, "Videos")
self.dokCb = wx.CheckBox(self.checkPnl, -1, "Dokumente")
self.sonstigeCb = wx.CheckBox(self.checkPnl, -1, "Sonstige")
self.hospitalCb = wx.CheckBox(self.checkPnl, -1, "Aufenthalte Krankenhaus")
self.opCb = wx.CheckBox(self.checkPnl, -1, "Operationen")
'''
self.mediCb = wx.CheckBox(self.checkPnl, -1, "Medikation")
sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
sizer_1.Add(self.bilderCb, 0, 0, 0)
'''
sizer_1.Add(self.videoCb, 0, 0, 0)
sizer_1.Add(self.dokCb, 0, 0, 0)
sizer_1.Add(self.sonstigeCb, 0, 0, 0)
sizer_1.Add((50, 20), 0, 0, 0)
sizer_1.Add(self.hospitalCb, 0, 0, 0)
sizer_1.Add(self.opCb, 0, 0, 0)
'''
sizer_1.Add(self.mediCb, 0, 0, 0)
'''
'''
self.checkPnl.SetSizer(sizer_1)
self.SetSizer(self.controlSizer)
class ViewPanel(wx.Panel):
def __init__(self, *args, **kwds):
wx.Panel.__init__(self, *args, **kwds)
#self.model = self.Parent.model
Wenn ich nun eine OnPaint-Methode zum zeichnen verwenden, soll diese in der Klasse mit den Panels oder in der "Logik"-Klasse ausgeführt werden? Der Untscherschied leuchtet mir nicht ein.
Was mir zudem noch aufgefallen ist: wenn ich den EVT_PAINT binde, werden bei mir Tooltips nicht angezeigt. Kommentiere ich den entsprechenden Aufruf aus (=OnPaint wird nicht mehr ausgeführt), erscheinen die Tooltips. Hängt das irgendwie zusammen? Puh, viele Fragen meinerseits, aber wenn ich für die Unterstützung nicht so dankbar wäre würde ich es sein lassen. Also nochmals danke!