Maus Event wird unter Toolbar-Icon nicht erkannt

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Kegelkugel
User
Beiträge: 32
Registriert: Samstag 8. Januar 2011, 13:37
Wohnort: München
Kontaktdaten:

Hallo,

ich habe folgendes Problem: ich hab' eine Toolbar mit einem Icon. Direkt unter dem Icon werden keine Maus-Events erkannt (weder EVT_LEFT_DOWN, noch EVT_LEFT_UP oder MOTION). Hier ein Screenshot, in dem man sieht, wo die Maus noch erkannt wird, und wo nicht mehr: http://www.kegelkugel.bplaced.de/data/H ... Fehler.png
Der "Fehler" tritt nur auf, wenn ich ein Icon bzw. eine Toolbar dort habe und dann nur dort.
Kann mir jemand helfen oder kennt das Problem?
Danke!

Grüße,
kegelkugel
Zuletzt geändert von Kegelkugel am Freitag 25. November 2011, 17:56, insgesamt 1-mal geändert.
Kegelkugel
User
Beiträge: 32
Registriert: Samstag 8. Januar 2011, 13:37
Wohnort: München
Kontaktdaten:

Hier noch der Quell-Code:

Code: Alles auswählen

class EditorHandWindow(wx.Frame):
	def __init__(self, parent):
		self.parent = parent
		self.dots = []

		wx.Frame.__init__(self, parent, -1, 'Handschrift-Editor', size = (210*2, 297*2+65), style= wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.CAPTION)
		self.Bind(wx.EVT_CLOSE, self.OnClose)
		self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
		self.Bind(wx.EVT_ACTIVATE, self.OnPaint)
		self.SetBackgroundColour('white')
		self.Centre()

		toolbar = self.CreateToolBar()
		save = toolbar.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('data/images/save.png'))
		toolbar.Realize()

		self.OnPaint(None)
		self.Show(True)

	def OnClose(self, event):
		print "close"
		self.Destroy()

	def OnClick(self, event):
		self.dots.append(event.GetPosition())
		self.OnPaint(None)
	
	def OnPaint(self, event):
		dc = wx.PaintDC(self)
		dc.Clear()
		for dot in self.dots:
			dc.DrawPoint(dot[0], dot[1])            # x, y Wert
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

Mit einem "funktionierenden" Beispiel zum reproduzieren wäre hier vielleicht etwas mehr los ;)
Kegelkugel
User
Beiträge: 32
Registriert: Samstag 8. Januar 2011, 13:37
Wohnort: München
Kontaktdaten:

Code: Alles auswählen

import wx

class EditorHandWindow(wx.Frame):
        def __init__(self, parent):
                self.parent = parent
                self.dots = []

                wx.Frame.__init__(self, parent, -1, 'Handschrift-Editor', size = (210*2, 297*2+65), style= wx.CLOSE_BOX | wx.SYSTEM_MENU | wx.CAPTION)
                self.Bind(wx.EVT_CLOSE, self.OnClose)
                self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
                self.Bind(wx.EVT_ACTIVATE, self.OnPaint)
                self.SetBackgroundColour('white')
                self.Centre()

                toolbar = self.CreateToolBar()
                save = toolbar.AddLabelTool(wx.ID_ANY, '', wx.Bitmap('data/images/save.png'))
                toolbar.Realize()

                self.OnPaint(None)
                self.Show(True)

        def OnClose(self, event):
                print "close"
                self.Destroy()

        def OnClick(self, event):
                self.dots.append(event.GetPosition())
                self.OnPaint(None)
       
        def OnPaint(self, event):
                dc = wx.PaintDC(self)
                dc.Clear()
                for dot in self.dots:
                        dc.DrawPoint(dot[0], dot[1])            # x, y Wert
                        
app = wx.App()
EditorHandWindow(None)
app.MainLoop()
Ich hab' jetzt die "import" Zeile, und die drei Zeilen am Schluss hinzugefügt. Bei mir klappt's. Als Bild könnt ihr einfach irgendein Bild verwenden, damit ihr seht, was ich meine. Klickt man unter das Bild, wird der Punkt nicht gezeichnet.

Grüße,
Markus
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

"Das" funktioniert bei dir? Also ich bekomme folgenden Fehler, wie auch beim vorherigen Beispiel:

C++ assertion "wxAssertFailure" failed at ..\..\src\msw\dcclient.cpp(219) in wxP
aintDC::wxPaintDC(): wxPaintDC may be created only in EVT_PAINT handler!
Kegelkugel
User
Beiträge: 32
Registriert: Samstag 8. Januar 2011, 13:37
Wohnort: München
Kontaktdaten:

Ja, das funktioniert bei mir ;-)

Python 2.7.2
wxPython 2.8.11.0 (gtk2-unicode)
Ubuntu Linux 11.10

Du kannst ja die "OnPaint(None)" Aufrufe weglassen. Dann musst du aber das Fenster verschieben, damit du die Punkte siehst. Vielleicht klappt's dann bei dir.
Gremlin
User
Beiträge: 166
Registriert: Freitag 28. Mai 2010, 23:49

Kegelkugel hat geschrieben:Ubuntu Linux 11.10
Da liegt der Hund wohl begraben. Ich nutze Windows. ;)

Kann dir also nicht weiterhelfen, denn selbst mit einem Refresh bzw. Update im OnClick event bewirkt die DrawPoint Methode nichts. :K
Kegelkugel
User
Beiträge: 32
Registriert: Samstag 8. Januar 2011, 13:37
Wohnort: München
Kontaktdaten:

Ok, trotzdem Danke :-)
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Mh bei mir funktioniert es, evt. mal in der Mailingliste oder auf irc.freenode.net#wxpython fragen, wenn sich hier keiner mehr meldet.
the more they change the more they stay the same
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

@OP: Ich habe dein Beispiel etwas umschreiben müssen, damit es überhaupt funktioniert (auch Windows). Grundsätzlich sollte man ein wx.PaintDC nicht "einfach so" erzeugen. Wenn ich mich richtig erinnere, dann ist das sogar dokumentiert.

Der richtige Weg ist, wx.EVT_PAINT mit OnPaint zu verbinden. Hier MUSS dann ein PaintDC erzeugt werden. Manuell aktuallisieren kann man mit der Methode Refresh, welche ihrerseits einen EVT_PAINT auslöst. OnPaint darf demnach NICHT manuell aufgerufen werden.

Korrigierte Fassung:
http://paste.pocoo.org/show/520976/

---

Bei mir trat nun allerdings folgendes Phänomen auf:

Die Positionen aus event.GetPosition waren vertikal versetzt um die Höhe der Toolbar.

Darauf hin habe ich eine neue Version entwickelt, welches für das Click&Paint-Ding ein eigenes Panel vorsieht. Dieses verhält sich erwartungsgemäß:
http://paste.pocoo.org/show/520977/

Fazit: Nicht auf die event-Positionen in "blanken" Frames verlassen. Panels bieten zudem die Möglichkeiten, die Widgets wiederzuverwenden. Sicherlich ist dieses Verhalten irgendwo dokumentiert, aber allzusehr stecke ich auch nicht in der Materie.

Grüße ...
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Kegelkugel
User
Beiträge: 32
Registriert: Samstag 8. Januar 2011, 13:37
Wohnort: München
Kontaktdaten:

Hallo,

tut mir leid, dass ich mich nicht gemeldet hab', aber ich hatte irgendwie keine Benachrichtigung bekommen (oder nicht gelesen oder irgendetwas anderes), die mich daran erinnert, dass hier eine Antwort geschrieben wurde. Ich bin jetzt nur durch Zufall wieder auf das Thema gestoßen. Entschuldigung. :(

Zurück zum Thema: ich hab' deine Beispiele ausprobiert, es gab aber wieder das gleiche Problem wie zuvor. Die Klicks werden nicht erkannt.

Trotzdem Danke! :)

Grüße,
kegelkugel
Antworten