[wxPython] Tab in wxTextCtrl?

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[wxPython] Tab in wxTextCtrl?

Bruce Rabine
First the basics:
        wxPython: 2.1b3
        Python: 1.5.2
        wxWindows: 2.1r9
        platform: NT4.0,sp5

Now the problem:
        I'm trying to use a multiline wxTextCtrl for a simplistic
file editor and pressing the TAB key always advances focus to the next
widget on the Frame instead of inserting a TAB into the wxTextCtrl.

I've tried extending/overriding the OnChar method of wxTextCtrl, but it
never even seems to get called when the TAB key gets pressed (but it works
fine with handling any other key presses).

I've also tried separating this wxTextCtrl out onto its own wxPanel which
is placed on the parent panel and turning off tab traversal by specifying
'style=0' for the panel, but this didn't seem to have any effect.

I've also tried using EVT_CHAR or EVT_CHAR_HOOK (?what is the difference?)
macros tied to the wxTextCtrl.  Again the TAB key seems to never get to
the handler for these macros -- the focus advances here too.

I would appreciate any assistance with this problem.
Thanx in advance!

Bruce

p.s. I've attached the entire code file (I didn't feel like taking
        the time to make a cut-down version to include here.)
        It can either be run standalone, or from the demo (with minor
        modifications to Main.py)  The Print and Save buttons aren't
        implemented yet.

+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Bruce Rabine              e-mail:  [hidden email] |
| Secure Computing Corp.                                              |
| 2675 Long Lake Road                                                 |
| Roseville, MN 55113, USA     web:           www.securecomputing.com |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +


#!/usr/bin/env python
#----------------------------------------------------------------------------
# Name: CobraEdit.py
# Purpose:      This window is the new ACL grid window.
#
# Author:       Bruce Rabine
#
# Created:      A long time ago, in a galaxy far, far away...
#----------------------------------------------------------------------------


## import all of the wxPython GUI package
from wxPython.wx import *

#-------------------------------------------------------------------------
#  Create a class derived from the wxPython panel.
class ceTextCtrl(wxTextCtrl):

    def OnChar(self, event):
        # event is of type wxKeyEvent
        print "In OnChar, char = %s" % event.KeyCode()
        if (event.KeyCode() == WXK_TAB):
                print "Encountered a TAB char..."
        else:
                event.Skip()

#-------------------------------------------------------------------------
#  Create a class derived from the wxPython panel.
class CobraEdit(wxPanel):

    def __init__(self, parent, frame,
                initialFile="", permitBrowsing=true,
                readOnly=false, allowPrinting=false):

        # Add a panel
        wxPanel.__init__(self, parent, -1)
        self.SetAutoLayout(true)

        # Save the parent frame (for messages, etc)
        self.frame = frame
        # Full path to initial file to open
        self.initialFile = initialFile
        # flag to permit changing of file being edited
        self.permitBrowsing = permitBrowsing
        # flag to disallow editing the current file
        self.readOnly = readOnly
        # flag to give a print button...
        self.allowPrinting = allowPrinting

        # This flag is used to detect file modifications
        self.FileMod = false

        # Constrain panel to be same size as parent.
        c = wxLayoutConstraints()
        c.left.SameAs(parent, wxLeft, 0)
        c.top.SameAs(parent, wxTop, 0)
        c.bottom.SameAs(parent, wxBottom, 0)
        c.right.SameAs(parent, wxRight, 0)
        self.SetConstraints(c)

        #
        # Create the OK and Cancel buttons
        #
        if (self.allowPrinting):
                self.printButton = wxButton(self, -1, "Print...")
                self.printButton.SetToolTip(wxToolTip("Print the current file..."))
                EVT_BUTTON(self.printButton, self.printButton.GetId(),
                        self.OnPrintPressed)

        self.ok = wxButton(self, wxID_OK, "Save")
        self.ok.SetToolTip(wxToolTip("Press this to save changes"))
        EVT_BUTTON(self.ok, wxID_OK, self.OnOkPressed)
        self.ok.Enable(false) # initially disabled.

        self.cancel = wxButton(self, wxID_CANCEL, "Close")
        self.cancel.SetToolTip(wxToolTip("Press this to close window"))
        EVT_BUTTON(self.cancel, wxID_CANCEL, self.OnCancelPressed)
        lc = wxLayoutConstraints()
        lc.right.SameAs(self, wxRight, 10)
        lc.bottom.SameAs(self, wxBottom, 10)
        lc.width.Absolute(75)
        lc.height.Absolute(20)
        self.cancel.SetConstraints(lc)

        lc = wxLayoutConstraints()
        lc.right.SameAs(self.cancel, wxLeft, 10)
        lc.bottom.SameAs(self.cancel, wxBottom, 0)
        lc.width.Absolute(75)
        lc.height.Absolute(20)
        self.ok.SetConstraints(lc)

        if (self.allowPrinting):
                lc = wxLayoutConstraints()
                lc.right.SameAs(self.ok, wxLeft, 10)
                lc.bottom.SameAs(self.ok, wxBottom, 0)
                lc.width.Absolute(75)
                lc.height.Absolute(20)
                self.printButton.SetConstraints(lc)
                if (self.initialFile == ""):
                        self.printButton.Enable(false)

        self.FileNameLbl = wxStaticText(self, -1, "File: ")
        lc = wxLayoutConstraints()
        lc.left.SameAs(self, wxLeft, 20)
        lc.top.SameAs(self, wxTop, 20)
        lc.width.AsIs()
        lc.height.AsIs()
        self.FileNameLbl.SetConstraints(lc)

        self.FileName = wxTextCtrl(self, -1, "", style=wxTE_PROCESS_ENTER)
        self.FileName.SetToolTip(wxToolTip("Enter the full-path filename to edit..."))
        EVT_TEXT_ENTER(self.FileName, self.FileName.GetId(),
                self.OnFileNameEntered)
        if (not self.permitBrowsing):
                self.FileName.SetEditable(false)

        self.FileBrowse = wxButton(self, -1, " Browse... ")
        self.FileBrowse.SetToolTip(wxToolTip(
                "Choose a file to edit..."))
        if (self.permitBrowsing):
                EVT_BUTTON(self.FileBrowse, self.FileBrowse.GetId(),
                        self.OnFileBrowse)
        else:
                self.FileBrowse.Enable(false)
        lc = wxLayoutConstraints()
        lc.right.SameAs(self, wxRight, 20)
        lc.top.SameAs(self.FileNameLbl, wxTop, -3)
        lc.width.Absolute(75)
        lc.height.Absolute(20)
        self.FileBrowse.SetConstraints(lc)

        lc = wxLayoutConstraints()
        lc.left.RightOf(self.FileNameLbl, 5)
        lc.top.SameAs(self.FileNameLbl, wxTop, -3)
        lc.right.LeftOf(self.FileBrowse, 20)
        lc.height.Absolute(20)
        self.FileName.SetConstraints(lc)


        self.textPanel = wxPanel(self, -1, style=0)
        lc = wxLayoutConstraints()
        lc.left.SameAs(self, wxLeft, 10)
        lc.right.SameAs(self, wxRight, 10)
        lc.top.SameAs(self.FileName, wxBottom, 20)
        lc.bottom.SameAs(self.ok, wxTop, 20)
        self.textPanel.SetConstraints(lc)

        if (self.readOnly):
                flags = wxTE_READONLY | wxTE_MULTILINE | wxHSCROLL
        else:
                flags = wxTE_MULTILINE | wxHSCROLL
# self.FileContents = wxTextCtrl(self, -1, "",
# wxDefaultPosition, wxDefaultSize, flags)
        self.FileContents = ceTextCtrl(self.textPanel, -1, "",
                wxDefaultPosition, wxDefaultSize, flags)
        self.FileContents.SetFont(wxFont(9, wxMODERN, wxNORMAL,
                wxNORMAL, false))
        if (not self.readOnly):
                EVT_TEXT(self.FileContents, self.FileContents.GetId(),
                        self.OnFileModified)
        """
        lc = wxLayoutConstraints()
        lc.left.SameAs(self, wxLeft, 10)
        lc.right.SameAs(self, wxRight, 10)
        lc.top.SameAs(self.FileName, wxBottom, 20)
        lc.bottom.SameAs(self.ok, wxTop, 20)
        self.FileContents.SetConstraints(lc)
        """
        lc = wxLayoutConstraints()
        lc.left.SameAs(self.textPanel, wxLeft)
        lc.right.SameAs(self.textPanel, wxRight)
        lc.top.SameAs(self.textPanel, wxTop)
        lc.bottom.SameAs(self.textPanel, wxBottom)
        self.FileContents.SetConstraints(lc)


        if (self.initialFile != ""):
                self.FileName.SetValue(self.initialFile)
                self.ReadFile(self.initialFile)



    def OnFileBrowse(self, event):
        if (self.FileMod):
                fnp = self.FileName.GetValue()
                msg = "Do you want to save changes made to '%s'?" % fnp
                dlg = wxMessageDialog(self, msg, "Save Changes?",
                        wxYES_NO|wxCANCEL|wxICON_QUESTION)
                value = dlg.ShowModal()
                dlg.Destroy()
                if (value == wxID_CANCEL):
                        # Bail out...
                        self.FileContents.SetFocus()
                        return
                elif (value == wxID_YES):
                        # Do Save, then continue with file chooser
                        self.DoSave()
                # if (value == wxID_NO), just continue...

        dlg = wxFileDialog(self.frame, "Choose a file", ".", "", "*.*", wxOPEN)
        if dlg.ShowModal() == wxID_OK:
                newFile = dlg.GetPath()
                print ('OnFileBrowse selected: %s\n' % newFile)
                self.FileName.SetValue(newFile)
                self.ReadFile(newFile)
        dlg.Destroy()


    def ReadFile(self, fileName):
        if (self.FileContents.LoadFile(fileName)):
                try:
                    msg = "Successfully opened %s" % fileName
                    self.frame.SetStatusText(msg)
                except:
                    pass
                # clear the modified flag...
                self.FileMod = false
                # and disable the OK button...
                self.ok.Enable(false)
                # check the print button...
                if (self.allowPrinting):
                        self.printButton.Enable(true)
        else:
                msg = "Cannot open file: %s" % fileName
                self.FileContents.SetValue(msg)
        self.FileContents.SetInsertionPoint(0)
        self.FileContents.ShowPosition(0)
        self.FileContents.SetFocus()


    def OnFileNameEntered(self, event):
        # Does this ever get called ???
        # ? like when enter is pressed in the filename field ?

        fileName = self.FileName.GetValue()
        try:
            self.frame.SetStatusText("New FileName entered: %s" % fileName)
        except:
            pass
        self.ReadFile(fileName)



    def OnFileModified(self, event):
        self.FileMod = true
        self.ok.Enable(true)
        try:
            self.frame.SetStatusText("")
        except:
            pass

    def DoSave(self):
        print "Sorry, Save not implemented yet..."


    def OnOkPressed(self, event):
        print "Pressed OK..."


    def OnCancelPressed(self, event):
        if self.frame:
                self.frame.Close()
        else:
                self.Close()


    def OnPrintPressed(self, event):
        print "Pressed Print..."



    def OnCloseWindow(self, event):
        if (self.FileMod):
                fnp = self.FileName.GetValue()
                msg = "Do you want to save changes made to '%s'?" % fnp
                dlg = wxMessageDialog(self, msg, "Save Changes?",
                        wxYES_NO|wxCANCEL|wxICON_QUESTION)
                value = dlg.ShowModal()
                dlg.Destroy()
                if (value == wxID_CANCEL):
                        # cancel the close operation...
                        if (event.CanVeto() == true):
                                self.FileContents.SetFocus()
                                event.Veto(true)
                else:
                        if (value == wxID_YES):
                                print "Doing wxYES..."
                                self.DoSave()

                        # perform the close for either Yes or No
                        if (self.frame):
                            self.frame.Destroy()
                        else:
                            self.Destroy()
        else:
                # contents weren't modified, just close
                if (self.frame):
                        self.frame.Destroy()
                else:
                        self.Destroy()

#---------------------------------------------------------------------------
# This method is used when called from Cobra.
#---------------------------------------------------------------------------
def getWindow(frame, nb, log):
 
        initFile=""
        permitBrowsing=true
        readOnly=false
        allowPrinting=false

        win = CobraEdit(nb, frame,
                initFile, permitBrowsing,
                readOnly, allowPrinting)
        return win


#---------------------------------------------------------------------------
# This is used for displaying the window as stand-alone
#---------------------------------------------------------------------------
if __name__ == "__main__":

    class MainFrame(wxFrame):
        def __init__(self):
                wxFrame.__init__(self, NULL, -1, "Cobra Editor",
                        wxPoint(100, 100), wxSize(400, 400))
                self.sb = self.CreateStatusBar()
                self.SetAutoLayout(true)

                self.panel = CobraEdit(self, self,
### "D:\\fusion\\COBRA\\admin.readme",
                        "",
                        true, false, true)

        def OnCloseWindow(self, event):
                self.panel.OnCloseWindow(event)


    # Every wxWindows application must have a class derived from wxApp
    class TestApp(wxApp):

        # wxWindows calls this method to initialize the application
        def OnInit(self):

            # Create an instance of our customized Frame class
            frame = MainFrame()
            frame.Show(true)

            # Tell wxWindows that this is our main window
            self.SetTopWindow(frame)

            # Return a success flag
            return true


    app = TestApp(0) # Create an instance of the application class
    app.MainLoop() # Tell it to start processing events


#---------------------------------------------------------------------------



overview = "This is the overview for the Cobra Edit window..."


Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] Tab in wxTextCtrl?

Robin Dunn
>
> Now the problem:
> I'm trying to use a multiline wxTextCtrl for a simplistic
> file editor and pressing the TAB key always advances focus to the next
> widget on the Frame instead of inserting a TAB into the wxTextCtrl.
>
> I've tried extending/overriding the OnChar method of wxTextCtrl, but it
> never even seems to get called when the TAB key gets pressed (but it works
> fine with handling any other key presses).
>
> I've also tried separating this wxTextCtrl out onto its own wxPanel which
> is placed on the parent panel and turning off tab traversal by specifying
> 'style=0' for the panel, but this didn't seem to have any effect.
>

Removing the wxTAB_TRAVERSAL for the top-most wxPanel does the trick, of
course it also breaks tab-traversal for the rest of the controls too.  The
reason for this is that Panels and Dialogs get first crack at any navigation
key events that happen in any of their children (or grandchildren, etc.)
before the actual window with focus gets it.  This way keyboard navigation
is handled by the tep-level panel and can take care of issues such as
sub-panels and such, and won't have to rely on sub-windows cooperating
together to handle navigation issues.

> I've also tried using EVT_CHAR or EVT_CHAR_HOOK (?what is the difference?)

EVT_CHAR_HOOK is supposed to allow you to catch non-modifier keystrokes
before they are proccessed by child windows, but I couldn't make it work in
this case.

There are also lower level key events, EVT_KEY_UP and EVT_KEY_DOWN that you
might be able to use to work around this.

--
Robin Dunn
Software Craftsman
[hidden email]
http://AllDunn.com/robin/
http://AllDunn.com/wxPython/  Check it out!



_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users