0

I'm trying to learn wxPython. Unfortunately when I came to China in Jan I had to leave the nice wxPython book in Canada because it was too heavy for my suitcase. So I humbly ask you to bear with my ignorance.

As practice (and because I have a practical use for it) I want to read in a textfile and display the text line by line. Much to my surprise & delight, the following program actually works!

''' TextFileDisp00.py
'''

import wx
import codecs

#-------------------
class TextFrame(wx.Frame):

    def __init__(self, parent, mytitle, mysize):
        wx.Frame.__init__(self, parent, -1, mytitle, mysize)
        self.menubar = wx.MenuBar()
        self.file = wx.Menu()
        self.SetMenuBar(self.menubar)
        self.menubar.Append(self.file,'&File')
        self.openitem = self.file.Append(wx.ID_ANY,'&Open')
        self.Bind(wx.EVT_MENU,self.openevent,self.openitem)
        self.runitem = self.file.Append(wx.ID_ANY,'&Run')
        self.Bind(wx.EVT_MENU,self.runevent,self.runitem)
        self.exititem = self.file.Append(wx.ID_ANY,'E&xit')
        self.Bind(wx.EVT_MENU,self.exitevent,self.exititem)

        self.background = wx.Panel(self)
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.background, proportion=0, flag=wx.EXPAND)
        self.SetSizer(self.vbox)
        self.fileisopen = False
        self.Show()

    def openevent(self, event):
        filedialog = wx.FileDialog(self,
            message = 'Open text file',
            defaultDir = '.',
            defaultFile = 'TestTOC.txt',
            wildcard = 'Text file (*.txt;*.prn)| *.txt;*.prn',
            style = wx.OPEN)
        if filedialog.ShowModal() == wx.ID_OK:
            self.path = filedialog.GetPath()
            self.fileisopen = True

    def runevent(self, event):
        if not self.fileisopen:
            msgbox = wx.MessageDialog(self.background, message="No file is open!", style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Destroy()
        else:
            myOK = True
            linenr = 0
            InFile = codecs.open(self.path, 'r')
            textline = InFile.readline()
            while textline <> '' and myOK:
                linenr += 1
                msg = "Line " + repr(linenr) + ": " + textline
                msgbox = wx.MessageDialog(self.background, message=msg, style=wx.OK+wx.CANCEL)
                if msgbox.ShowModal() == wx.ID_CANCEL:
                    myOK = False
                msgbox.Destroy()
                textline = InFile.readline()
            msg = "Finished, # lines = " + repr(linenr)
            msgbox = wx.MessageDialog(self.background, message=msg, style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Destroy()
            InFile.close()
            self.Destroy()

    def exitevent(self, event):
        self.Destroy()

#-------------------
''' Main application
'''

app = wx.App(redirect = False)
mywidth = 300
myheight = 150
mytitle = "Text file display"
frame = TextFrame(None, mytitle, (mywidth,myheight))
app.MainLoop()

I would appreciate the comments of experienced users about style and things I have not understood. I have a couple of specific questions as well:

1. I don't seem to understand sizers, and I can't make the background panel extend to the bottom of the app window.

2. I would like to display the text much bigger, i.e. in a (possibly multiline) textbox in which I could set font and font color & size. But I would still like to use a modal box, so I can press Enter to see the next line. How is this done?

Thanks for your help and understanding! Next time my questions might be smarter.

3
Contributors
7
Replies
9
Views
7 Years
Discussion Span
Last Post by BigTurtle
0

Corrected your code a little and it works just fine:

''' TextFileDisp00.py
'''

import wx
import codecs

#-------------------
class TextFrame(wx.Frame):

    def __init__(self, parent, mytitle, mysize):
        wx.Frame.__init__(self, parent, -1, mytitle, mysize)
        self.menubar = wx.MenuBar()
        self.file = wx.Menu()
        self.SetMenuBar(self.menubar)
        self.menubar.Append(self.file,'&File')
        self.openitem = self.file.Append(wx.ID_ANY,'&Open')
        self.Bind(wx.EVT_MENU,self.openevent,self.openitem)
        self.runitem = self.file.Append(wx.ID_ANY,'&Run')
        self.Bind(wx.EVT_MENU,self.runevent,self.runitem)
        self.exititem = self.file.Append(wx.ID_ANY,'E&xit')
        self.Bind(wx.EVT_MENU,self.exitevent,self.exititem)

        self.background = wx.Panel(self)
        self.background.SetBackgroundColour("white")
        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.background, proportion=1, flag=wx.EXPAND)  #!!!!
        self.SetSizer(self.vbox)
        self.fileisopen = False
        self.Show()

    def openevent(self, event):
        filedialog = wx.FileDialog(self,
            message = 'Open text file',
            defaultDir = '.',
            defaultFile = 'TestTOC.txt',
            wildcard = 'Textfile (.txt .prn)|*.txt;*.prn|All (.*)|*.*', #!!!!
            style = wx.OPEN)
        if filedialog.ShowModal() == wx.ID_OK:
            self.path = filedialog.GetPath()
            self.fileisopen = True

    def runevent(self, event):
        if not self.fileisopen:
            msgbox = wx.MessageDialog(self.background,
                message="No file is open!", style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Destroy()
        else:
            myOK = True
            linenr = 0
            InFile = codecs.open(self.path, 'r')
            textline = InFile.readline()
            while textline <> '' and myOK:
                linenr += 1
                msg = "Line " + repr(linenr) + ": " + textline
                msgbox = wx.MessageDialog(self.background,
                    message=msg, style=wx.OK+wx.CANCEL)
                if msgbox.ShowModal() == wx.ID_CANCEL:
                    myOK = False
                msgbox.Destroy()
                textline = InFile.readline()
            msg = "Finished, # lines = " + repr(linenr)
            msgbox = wx.MessageDialog(self.background,
                message=msg, style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Destroy()
            InFile.close()
            self.Destroy()

    def exitevent(self, event):
        self.Destroy()

#-------------------
''' Main application
'''

app = wx.App(redirect = False)
mywidth = 300
myheight = 150
mytitle = "Text file display"
frame = TextFrame(None, mytitle, (mywidth,myheight))
app.MainLoop()

Line one of wx.AboutBox() has a larger font, maybe you can use that. See:
http://www.daniweb.com/forums/post901743-112.html

0

Sneekula, thanks for your reply! From your comments I conclude that a modal dialog is too limited for the kind of display I want. Here's a second try at displaying all lines of a file sequentially, using a text box instead. But it doesn't wait for me to press Enter, so all I see is the last line of the file. What to do?

import wx
import codecs

#-------------------
class TextFrame(wx.Frame):

    def __init__(self, parent, mytitle, mysize):
        wx.Frame.__init__(self, parent, -1, mytitle, mysize)
        self.menubar = wx.MenuBar()
        self.file = wx.Menu()
        self.SetMenuBar(self.menubar)
        self.menubar.Append(self.file,'&File')
        self.openitem = self.file.Append(wx.ID_ANY,'&Open')
        self.Bind(wx.EVT_MENU,self.openevent,self.openitem)
        self.runitem = self.file.Append(wx.ID_ANY,'&Run')
        self.Bind(wx.EVT_MENU,self.runevent,self.runitem)
        self.exititem = self.file.Append(wx.ID_ANY,'E&xit')
        self.Bind(wx.EVT_MENU,self.exitevent,self.exititem)

        self.background = wx.Panel(self)
        self.background.SetBackgroundColour("white")

        self.textdisp = wx.TextCtrl(self.background, 100,
            style = wx.TE_READONLY | wx.TE_MULTILINE | wx.TE_PROCESS_ENTER)
        wx.EVT_TEXT_ENTER ( self.background, 100, self.handleEnter )

        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.textdisp, proportion=1, border=0, flag=wx.EXPAND)
        self.background.SetSizer(self.vbox)
        self.fileisopen = False
        self.Show()

    def handleEnter(self, event):
        pass # ?? what to do?

    def openevent(self, event):
        filedialog = wx.FileDialog(self,
            message = 'Open text file',
            defaultDir = '.',
            defaultFile = 'TestTOC.txt',
            wildcard = 'Text file (*.txt;*.prn)| *.txt;*.prn',
            style = wx.OPEN)
        if filedialog.ShowModal() == wx.ID_OK:
            self.path = filedialog.GetPath()
            self.fileisopen = True

# Display the lines of the file sequentially. Wait for <Enter> between lines -- how??

    def runevent(self, event):
        if not self.fileisopen:
            msgbox = wx.MessageDialog(self.background, message="No file is open!", style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Destroy()
        else:
            myOK = True
            linenr = 0
            InFile = codecs.open(self.path, 'r')
            textline = InFile.readline()
            while textline <> '' and myOK:
                linenr += 1
                textstr = "Line " + repr(linenr) + ": " + textline
                self.textdisp.SetValue(textstr) # ?? Now I want to wait for <Enter>

                textline = InFile.readline()
            msg = "Finished, # lines = " + repr(linenr)
            msgbox = wx.MessageDialog(self.background, message=msg, style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Destroy()
            InFile.close()
            self.Destroy()

    def exitevent(self, event):
        self.Close(True)

#-------------------
''' Main application
'''
app = wx.App(redirect = False)
mywidth = 300
myheight = 150
mytitle = "Text file display"
frame = TextFrame(None, mytitle, (mywidth,myheight))
app.MainLoop()

If I can get this working, then I'll replace the TextCtrl by a RichTextCtrl (?) that will allow me to change font size etc., but first things first.

:'( It's VERY difficult to find the documentation I need on the Web. Is there a place where things like wx.TE_PROCESS_ENTER and wx.EVT_TEXT_ENTER are actually explained? I truly hate blundering around in the dark like this.

Thanks again for your help (and anyone else's who wants to)!

0

Excuse me! I'm really not clever yet with GUI programming, my apologies! I just realized that the behavior I want from the Enter key has nothing to do with the textbox display, which after all is just showing stuff out of the file. Here's a version that does what I want.

import wx
import codecs

#-------------------
class TextFrame(wx.Frame):

    def __init__(self, parent, mytitle, mysize):
        wx.Frame.__init__(self, parent, -1, mytitle, mysize)
        self.menubar = wx.MenuBar()
        self.file = wx.Menu()
        self.SetMenuBar(self.menubar)
        self.menubar.Append(self.file,'&File')
        self.openitem = self.file.Append(wx.ID_ANY,'&Open')
        self.Bind(wx.EVT_MENU,self.openevent,self.openitem)
        self.runitem = self.file.Append(wx.ID_ANY,'&Run')
        self.Bind(wx.EVT_MENU,self.runevent,self.runitem)
        self.exititem = self.file.Append(wx.ID_ANY,'E&xit')
        self.Bind(wx.EVT_MENU,self.exitevent,self.exititem)

        self.background = wx.Panel(self)
        self.background.SetBackgroundColour("white")

        self.textdisp = wx.TextCtrl(self.background, 100,
            style = wx.TE_READONLY | wx.TE_MULTILINE)

        self.vbox = wx.BoxSizer(wx.VERTICAL)
        self.vbox.Add(self.textdisp, proportion=1, border=0, flag=wx.EXPAND)
        self.background.SetSizer(self.vbox)
        self.fileisopen = False
        self.myOK = True
        self.Show()

    def openevent(self, event):
        filedialog = wx.FileDialog(self,
            message = 'Open text file',
            defaultDir = '.',
            defaultFile = 'TestTOC.txt',
            wildcard = 'Text file (*.txt;*.prn)| *.txt;*.prn',
            style = wx.OPEN)
        if filedialog.ShowModal() == wx.ID_OK:
            self.path = filedialog.GetPath()
            self.fileisopen = True

# Display the lines of the file sequentially. Wait for <Enter> between lines by posting a modal message box.

    def runevent(self, event):
        if not self.fileisopen:
            msgbox = wx.MessageDialog(self.background, message="No file is open!", style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Close(True)
        else:
            self.myOK = True
            linenr = 0
            InFile = codecs.open(self.path, 'r')
            textline = InFile.readline()
            while textline <> '' and self.myOK:
                linenr += 1
                textstr = "Line " + repr(linenr) + ": " + textline
                self.textdisp.SetValue(textstr)

                msg = 'Show next line?'
                msgbox = wx.MessageDialog(self.background, message=msg, style=wx.YES_NO)
                if msgbox.ShowModal() == wx.ID_NO:
                    self.myOK = False
                msgbox.Close(True)

                textline = InFile.readline()
            msg = "Finished, # lines = " + repr(linenr)
            msgbox = wx.MessageDialog(self.background, message=msg, style=wx.OK)
            if msgbox.ShowModal() == wx.ID_OK:
                msgbox.Destroy()
            InFile.close()
            self.Destroy()

    def exitevent(self, event):
#        self.Destroy()
        self.Close(True)

#-------------------
''' Main application
'''

app = wx.App(redirect = False)
mywidth = 300
myheight = 150
mytitle = "Text file display"
frame = TextFrame(None, mytitle, (mywidth,myheight))
app.MainLoop()

Now every line of the file displays separately, and I can continue viewing by pressing Enter or quit by choosing NO.

Ideally I would want my message box to be invisible and just respond to Enter to continue, and to some other key, say Esc, to pause, resume at a different line, open another file, or quit. Are there any invisible message boxes on the market?

My deep apologies if you read the previous message uselessly. I would have edited or deleted it but didn't know how.

0

I guess the person who developed wxPython as a wrapper for wxWindows (written in C++) didn't do much about documentation, leaving that to his book he published later. The rub was that the editor of the book introduced a lot of errors and made the book not very friendly to use.

0

I always use the wxPython api when i want to find something out, its a very very useful skill to be able to do that, because of the lack of documentation you really have to try and use what you do have.

I once wrote a small explanation on wxTextCtrl, ill attach it to the post, its a pdf. One bit of it goes over the side of the page, sorry bout that :P

Hope it helps

0

Sneekula, thanks for your help. I feel like my WxPython expertise has gone up from level 0 to at least 0.1. And I am reading the very clear GUI tutorials on this site, thanks for these too.

0

paulthom, thanks for your note. I learned most of the little I know about wxpython from your very practical tutorials on www.wxpython.webs.com/. The down-home language is entertaining and explicit. I like your layout on www.thecodecookie.com also, and am looking forward to seeing more. Thanks again!

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.