Seite 1 von 1

(gelöst)Linksklick-Event für ein TextCtrl?

Verfasst: Samstag 30. Januar 2010, 16:03
von Schaf220
Hallo liebe Community,
erneut bin ich auf ein Problem gestoßen, wofür es keine für mich verständlich Antwort gibt. Ich habe wie schon im Thread von vorhin "wx Fenster ohne Systembar?" erklärt das ich ein Sudokuspiel programmiere und bin auch schon ein guten Stück voran gekommen aber nun gehts nicht weiter.
Ich habe nun ein wxFrame mit 9 TextCtrl´s und den Zahlen 1-9.

Bild

Soweit so gut jetzt benötige ich ein MouseEvent für den Linksklick, das wenn ich mit der linken Maustaste auf eine Zahl klicke, der entsprechende Wert zurückgegeben wird und das Fenster anschließend terminiert wird.

Dazu habe ich mir schon mal das Mouseevent angeguckt:
http://docs.wxwidgets.org/2.8.6/wx_wxmo ... mouseevent

Ich weiß aber nicht genau wie man sich einen Eventhandler schreibt. Für einen Tipp oder eien kleien Anstoß wäre ich euch sehr dankbar.

EDIT:

Ich hab hier mal das Fenster was erzeugt wird. Ich hab auch schon das Mouseevent hinzugefügt, aber wenn jetzt auf eine Zahl geklickt wird, dann weiss ich noch nicht wie ich ihm sagen soll das es z.B. die 1 oder die 9 ist. Ich brauche die Referenz auf das angeklickte TextCtrl.

Bitte nicht den Code so stak bewerten das is alles noch "quick und dirty"

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import wx
#from gui_sudoku import SudokuFrame 

class ChoiseField(wx.Frame):
    """
    Main Frame
    """
    
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Zahlenauswahl", size=(150, 150), style = wx.CAPTION)
        self.panel = wx.Panel(self, -1)
        
        self.gridOut = wx.GridSizer(1,1)       

        row = []
        for elementX in range(9):
            newfield = wx.TextCtrl(parent = self.panel, id = -1, style = wx.TE_READONLY | wx.TE_CENTRE)
            row.append(newfield)

        font1 = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Comic Sans MS')
        gridIn = wx.GridSizer(3,3,2,2)
        num = 0
        for cell in row:
            num += 1                
            cell.SetFont(font1)
            cell.SetValue(str(num))
            gridIn.Add(cell, 1, wx.EXPAND | wx.ALL, 0)            
        
        self.gridOut.Add(gridIn, 1, wx.EXPAND | wx.ALL,0)
        self.panel.SetSizerAndFit(self.gridOut)           
        self.Centre()
        self.Show(True)
        
        
        for ctrl in range(9):
            row[ctrl].Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        
    def OnLeftDown(self, event):
        """left mouse button is pressed"""
        pt = event.GetPosition()  # position tuple
        print pt
         

if __name__ == "__main__":
    app = wx.App(False)
    frame = ChoiseField()
    app.MainLoop()


MfG Schaf220

Verfasst: Samstag 30. Januar 2010, 17:06
von Dav1d
Du könntest Button verwenden!

ansonsten

Code: Alles auswählen

self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down, id=12)

Verfasst: Samstag 30. Januar 2010, 17:19
von Schaf220
Das wäre eine Idee, aber ich würde das lieber mit TextCtrl lösen. Ich muss das nur igrentwie schaffen dem zusagen auf welches TextCtrl geklickt wurde.

Verfasst: Samstag 30. Januar 2010, 17:51
von Dav1d
Du kannst ja für jede ID ein neues Event setzten, stat wx.ID_ANY in Zeile 20 musst du eine ID vergeben

Verfasst: Samstag 30. Januar 2010, 18:28
von Schaf220
Das is eine Möglichkeit, und das funktioniert auch, aber wenn das mehr als 9 TextCtrl´s werden wie beim HauptFenster mit 81 TextCtrls, dann ist das einfach zu aufwendig.

Das Hauptproblem ist einfach heraus zu finden in welchem TextCtrl man sich befindet, wenn man in einen Kasten klickt.

Verfasst: Samstag 30. Januar 2010, 18:54
von Dav1d
verwende Listen bzw. Dicts, du bekommst die ID per event.getId(), wenn du jetzt ein dict hast mit den ID's als keys und die Instanz der TextCtrl als Value, sollte das kein Problem mehr darstellen

Du kannst dann auch mit "for" die TextCtrls erstellen

Verfasst: Samstag 30. Januar 2010, 19:32
von Schaf220
Die Erzeugung der TextCtrl´s habe ich schon dynamisch gemacht wie auch oben zu sehen. alle 9 TextCtrl´s sind in einer Liste und haben die ID 1-9.

Ok, ich benutze ein MouseEvent und dieses hat keine Methode die "getId()" hat.

Verfasst: Samstag 30. Januar 2010, 21:34
von Dav1d
Ich meine die Event-var die übergeben wird, wenn ein Eventhandler aufgerufen wird

Code: Alles auswählen

self.Bind(wx.EVT_I-WAS, self.event_handler, id=12)

def event_handler(self, event):
    print event.getId()

Verfasst: Sonntag 31. Januar 2010, 00:24
von Schaf220
Tut mir leid aber ich verstehe nicht ganz, was oder wie du das meinst. Könntest du mir das vieleicht anhand meines Beispiels oben erklären?

Verfasst: Sonntag 31. Januar 2010, 13:44
von Dav1d
Ich hoffe es hilft dir

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import wx
#from gui_sudoku import SudokuFrame

class ChoiseField(wx.Frame):
    """
    Main Frame
    """
   
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Zahlenauswahl", size=(150, 150), style = wx.CAPTION)
        self.panel = wx.Panel(self, -1)
       
        self.gridOut = wx.GridSizer(1,1)       

        self.txt_ctrls = {}
        for elementX in range(1,10):
            newfield = wx.TextCtrl(parent = self.panel, id = elementX, style = wx.TE_READONLY | wx.TE_CENTRE)
            self.txt_ctrls[elementX] = newfield

        font1 = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, u'Comic Sans MS')
        gridIn = wx.GridSizer(3,3,2,2)
        num = 0
        for num, cell in self.txt_ctrls.iteritems():
            cell.SetFont(font1)
            cell.SetValue(str(num))
            gridIn.Add(cell, 1, wx.EXPAND | wx.ALL, 0)           
       
        self.gridOut.Add(gridIn, 1, wx.EXPAND | wx.ALL,0)
        self.panel.SetSizerAndFit(self.gridOut)           
        self.Centre()
        self.Show(True)
       
       
        for ctrl in self.txt_ctrls.values():
            ctrl.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
       
    def OnLeftDown(self, event):
        """left mouse button is pressed"""
        ID = event.GetId()
        print 'ID', ID
        print 'TextCtrl', self.txt_ctrls[ID]
         

if __name__ == "__main__":
    app = wx.App(False)
    frame = ChoiseField()
    app.MainLoop()
Edit: Überschreiben von "id" ausgebessert

Verfasst: Sonntag 31. Januar 2010, 14:49
von Schaf220
Hey super das ist genau das, was ich gesucht habe! Vielen Dank das du dir die Zeit genommen hast, um mir bei diesem Problem zu helfen!

Verfasst: Sonntag 31. Januar 2010, 14:57
von Dav1d
Gerne, solche Probleme kenn ich nur zu gut ;)