SetSelection TextCtrl

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

Hallo!
Beim Start eines Frames möchte ich einen Teil des darin enthaltenen
TextCtrl markieren. Meine zwei Lösungsversuche haben leider nicht
geklappt. Was habe ich bei dem Problem übersehen?

Code: Alles auswählen

        self.text = wx.TextCtrl(self, -1, predef_question, pos=(115,15))

        self.text.SetSelection(start, end)
        self.Refresh()
--> alles wird markiert, als hätte ich SetSelection gar nicht aufgerufen.

Code: Alles auswählen

        self.SetFocus() #set focus to wx.Dialog frame
        self.text = wx.TextCtrl(self, -1, predef_question, pos=(115,15))
        def select():
            self.text.SetSelection(start, end)
            self.Refresh()
#            wx.Yield()

        self.Bind(wx.EVT_SET_FOCUS, select, self.text)
        self.text.SetFocus()

--> gar nichts wird markiert
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

bist du dir sicher, dass das Event im zweiten Fall auch wirklich eintritt?

Kannst du mal den ganzen Code auslagern und posten....
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

Es tritt leider nicht ein....

Code: Alles auswählen

import wx


class QuestionDialog(wx.Dialog):
    def __init__(self, ):
        wx.Dialog.__init__(self, None, -1, 'Question Dialog',
                size=(300, 100))

        predef_question="Wie sieht ... aus?"

        self.SetFocus()
        self.text = wx.TextCtrl(self, -1, predef_question, pos=(115,15))

#        start = predef_question.find("...")
#        end = start + 3
#
#        self.text.SetSelection(start, end)
#        self.Refresh()

        def select():
            print 'hello'
            start = predef_question.find("...")
            end = start + 3

            self.text.SetSelection(start, end)
            self.text.Refresh()
            self.Refresh()
            wx.Yield()

        self.Bind(wx.EVT_SET_FOCUS, select, self.text)
        self.text.SetFocus()

        okButton = wx.Button(self, wx.ID_OK, "OK", pos=(15, 15))
        okButton.SetDefault()


if __name__ == '__main__':
    app = wx.PySimpleApp()
    app.MainLoop()
    dialog = QuestionDialog()
    result = dialog.ShowModal()
    if result == wx.ID_OK:
        print "OK"
    else:
        print "Cancel"
    dialog.Destroy()

nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Was spricht gegen diese Lösung?

Vielliecht funktioniert es auch mit deinem Focus, wenn du das obere SetFocus rausnimmst, da es ja schon fokussiert ist und daher tritt das untere Event nicht mehr ein.

Code: Alles auswählen

import wx


class QuestionDialog(wx.Dialog):
    def __init__(self, ):
        wx.Dialog.__init__(self, None, -1, 'Question Dialog',
                size=(300, 100))
                
        predef_question="Wie sieht ... aus?"
        
        self.SetFocus()
        self.text = wx.TextCtrl(self, -1, predef_question, pos=(115,15))
        
        start = predef_question.find("...")
        end = start + 3
        self.text.SetSelection(start, end)
        
        okButton = wx.Button(self, wx.ID_OK, "OK", pos=(15, 15))
        okButton.SetDefault()


if __name__ == '__main__':
    app = wx.PySimpleApp()
    app.MainLoop()
    dialog = QuestionDialog()
    result = dialog.ShowModal()
    if result == wx.ID_OK:
        print "OK"
    else:
        print "Cancel"
    dialog.Destroy() 
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

... mein Ziel war es die drei Punkte auszuwählen ...
Vielliecht funktioniert es auch mit deinem Focus, wenn du das obere SetFocus rausnimmst, da es ja schon fokussiert ist und daher tritt das untere Event nicht mehr ein.
Bei dem ersten Codeausschnitt ist es auch nicht drin
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

also bei mir hat es einwandfrei funktioniert mit meinem Beispiel...
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Ich frage mich, wieso der Code ueberhaupt was tut, da die MainLoop ja ganz zu Anfang aufgerufen wird. Nach meinem Verstaendnis muesste die MainLoop sofort wieder verlassen werden, da zu dem Zeitpunkt ja noch keine Widgets da sind, und danach sollte ueberhaupt kein Event Handling mehr funktionieren, da ja "die wx-Anwendung" zu dem Zeitpunkt doch schon wieder zuende ist? :?:
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

@Rebecca: Da hast du Recht, hatte mal wieder nur Copy&Paste gemacht. Aber in der MainLoop() werden nur die Events verarbeitet, von daher funktioniert der Rest schon.

@Janux: Jetzt weißt du auch, warum die Events nicht greifen.
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

SchneiderWeisse hat geschrieben: @Janux: Jetzt weißt du auch, warum die Events nicht greifen.
Ja das hört sich logisch an, funktioniert aber leider bei mir (Windows XP)
auch nicht richtig wenn ich MainLoop() am Ende aufrufe.

Ich habe mal ein etwas längeres Beispiel erstellt und versucht es sinnvoll
zu kommentieren ... http://paste.pocoo.org/show/98134/
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Ich verstehe immer noch nicht, was du hiergegen hast:

Code: Alles auswählen

import wx


class QuestionDialog(wx.Dialog):
    def __init__(self, ):
        wx.Dialog.__init__(self, None, -1, 'Question Dialog',
                size=(300, 100))
                
        predef_question="Wie sieht ... aus?"
        
        self.SetFocus()
        self.text = wx.TextCtrl(self, -1, predef_question, pos=(115,15))
        
        start = predef_question.find("...")
        end = start + 3
        self.text.SetSelection(start, end)
        
        okButton = wx.Button(self, wx.ID_OK, "OK", pos=(15, 15))
        okButton.SetDefault()


if __name__ == '__main__':
    app = wx.PySimpleApp()
    dialog = QuestionDialog()
    result = dialog.ShowModal()
    if result == wx.ID_OK:
        print "OK"
    else:
        print "Cancel"
    dialog.Destroy()
    app.MainLoop()
    
bei mir funktioniert das einwandfrei und markiert auch nur die 3 Punkte...
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

Bei mir wird mit diesem Code nichts markiert :?
(Windows XP / EasyEclipse)

Womit hast du ihn denn aufgerufen?
mfg ... Janux
BlackJack

@Janux: Also wenn ich Deinen Quelltext für `QuestionDialog` vereinfache zu:

Code: Alles auswählen

class QuestionDialog(wx.Dialog):
    """
    A dialog which *should* select the three
    points in a string (`predef_question`) at startup
    """
    def __init__(self, predef_question):
        wx.Dialog.__init__(self, None, -1, 'Question Dialog', size=(300, 100))
        self.SetFocus()
        self.text = wx.TextCtrl(self, -1, predef_question, pos=(115,15))

        start = predef_question.find("...")
        self.text.SetSelection(start, start + 3)

        okButton = wx.Button(self, wx.ID_OK, "OK", pos=(15, 15))
        okButton.SetDefault()
Dann funktioniert es. Das Programm insgesamt hat aber das Problem, dass man es nicht ordentlich beenden kann nachdem der `QuestionDialog` mal auf dem Schirm war.
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

BlackJack hat geschrieben: Dann funktioniert es.
Bei mir leider nicht :(
BlackJack hat geschrieben: Das Programm insgesamt hat aber das Problem, dass man es nicht ordentlich beenden kann nachdem der `QuestionDialog` mal auf dem Schirm war.
Warum nicht?
mfg ... Janux
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

So funktioniert es auch bei mir:

Code: Alles auswählen


import wx

class QuestionDialog(wx.Dialog):
    def __init__(self, ):
        wx.Dialog.__init__(self, None, -1, 'Question Dialog',
                size=(300, 100))

        self.predef_question="Wie sieht ... aus?"

        self.SetFocus()
        self.text = wx.TextCtrl(self, -1, self.predef_question, pos=(115,15))

        okButton = wx.Button(self, wx.ID_OK, "OK", pos=(15, 15))
        okButton.SetDefault()

        wx.CallLater(1, self.SetSelection)

    def SetSelection(self):
        self.text.SetFocus()
        start = self.predef_question.find("...")
        self.text.SetSelection(start, start + 3)

if __name__ == '__main__':
    app = wx.PySimpleApp()

    dialog = QuestionDialog()
    result = dialog.ShowModal()
    if result == wx.ID_OK:
        print "OK"
    else:
        print "Cancel"
    dialog.Destroy()
    app.MainLoop()
Hier noch zwei Links falls jemand mal das gleiche Problem hat:

http://aspn.activestate.com/ASPN/Mail/M ... rs/2086832
http://lists.wxwidgets.org/pipermail/wx ... 75761.html

Danke für eure Bemühungen!
mfg ... Janux
Antworten