Trying to add wxButton to a wxPanel

Hello all!

I have a panel:

class TrafficPane(wx.Panel):

Initializer

the class constructor

def init(self, parent, msgq):

wx.Panel.init(self,
parent)

self.msgq = msgq

open a file named “logfile.txt”

in “a” append mode;

creates file if it doesn’t exist.

self.logfile =
open(‘logfile.txt’, ‘a’)

#layout of the panel. 10 px gap
on each side of TextCtrls. panel is a grid,

#texctrls and lables are placed
at grid positions like (1,1), (2,1) etc.

sizer =
wx.GridBagSizer(hgap=10, vgap=10)

defines a dictionary ({} = empty

dictionary), to hold the text control values

self.fields = {}

#TextCtrl recipe:

#creates the first label static text
on gui panel

label = wx.StaticText(self, -1,
“DUID:”)

#position on the gui panel
grid, top left

sizer.Add(label, pos=(1,1))

#create the textCtrl field,
give it a size, make it read-only

field = wx.TextCtrl(self, -1,
“”, size=(144, -1), style=wx.TE_READONLY)

#sticks TextCrtl to grid right
of label

sizer.Add(field, pos=(1,2))

#add the field for this
TextCtrl to the dictionary

self.fields[“duid”] =
field;

There are 8 more TextCtrls like this
one. I need to put an event button under the TextCtrls that will
trigger the wxFileDialog something like:

def openfile(self, event):

dlg = wx.FileDialog(self,
“Choose a file”, os.getcwd(), “”, “.”,
wx.OPEN)

if dlg.ShowModal() == wx.ID_OK:

path = dlg.GetPath()

mypath =
os.path.basename(path)

self.SetStatusText(“You
selected: %s” % mypath)

dlg.Destroy()

This is to allow the user to open/choose a logfile from the UI. This has got to be one of the most common
pieces of code a person will need but I have been having real trouble
find some standard pieces of code to do this.

Thanks in advance!

matt d wrote:

There are 8 more TextCtrls like this one. I need to put an event button
under the TextCtrls that will trigger the wxFileDialog something like:

def openfile(self, event):

dlg = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "*.*", wx.OPEN)

if dlg.ShowModal() == wx.ID_OK:

path = dlg.GetPath()

mypath = os.path.basename(path)

self.SetStatusText("You selected: %s" % mypath)

dlg.Destroy()

This is to allow the user to open/choose a logfile from the UI. This has
got to be one of the most common pieces of code a person will need but I
have been having real trouble find some standard pieces of code to do this.

To do what? Create the button? Manage it's layout size and/or position? Bind the event handler to the button's event? There are many examples of all of these in the demo, samples and the various examples on the wiki and elsewhere on the internet.

···

--
Robin Dunn
Software Craftsman

To do what? Create the button? Manage it’s layout size and/or
position? Bind the event handler to the button’s event? There are many
examples of all of these in the demo, samples and the various examples
on the wiki and elsewhere on the internet.

Yes i have seen the examples but i having a hard time putting it together with what I already have. Yes again I need to create the button, pin it to the grid i already have, and make it open the wxFileDialog, in order to allow me to choose the file which my logger will write to.
I would love to just use the same recipe as I did for the TextCtrls to stick the button to the UI (and then go from there with wxFileDialog) but its not working for me!?? I really stink at writing code and there is something thing that i just don’t get. None of the examples i have seen use the panel, its always an app or a frame or whatever and i get confused about this easily. I need to see the right way to do this.
I attached the .py file (minus all of my failed attempts at this) If you have any time to take a look at whats going on here and make a suggestion i will be greatly appreciative.

currentV_op25_traffic_pane.py (8.04 KB)

I’ve cleared out a lot of code to make a small runable snippet of your code with a button added that opens a file dialog.
http://bpaste.net/show/N2gsagPwEGjleFmuQ2yq/

···

On Wednesday, June 19, 2013 3:11:01 PM UTC+1, matt d wrote:

Hello all!

I have a panel:

class TrafficPane(wx.Panel):

Initializer

the class constructor

def init(self, parent, msgq):

wx.Panel.init(self,
parent)

self.msgq = msgq

open a file named “logfile.txt”

in “a” append mode;

creates file if it doesn’t exist.

self.logfile =
open(‘logfile.txt’, ‘a’)

#layout of the panel. 10 px gap
on each side of TextCtrls. panel is a grid,

#texctrls and lables are placed
at grid positions like (1,1), (2,1) etc.

sizer =
wx.GridBagSizer(hgap=10, vgap=10)

defines a dictionary ({} = empty

dictionary), to hold the text control values

self.fields = {}

#TextCtrl recipe:

#creates the first label static text
on gui panel

label = wx.StaticText(self, -1,
“DUID:”)

#position on the gui panel
grid, top left

sizer.Add(label, pos=(1,1))

#create the textCtrl field,
give it a size, make it read-only

field = wx.TextCtrl(self, -1,
“”, size=(144, -1), style=wx.TE_READONLY)

#sticks TextCrtl to grid right
of label

sizer.Add(field, pos=(1,2))

#add the field for this
TextCtrl to the dictionary

self.fields[“duid”] =
field;

There are 8 more TextCtrls like this
one. I need to put an event button under the TextCtrls that will
trigger the wxFileDialog something like:

def openfile(self, event):

dlg = wx.FileDialog(self,
“Choose a file”, os.getcwd(), “”, “.”,
wx.OPEN)

if dlg.ShowModal() == wx.ID_OK:

path = dlg.GetPath()

mypath =
os.path.basename(path)

self.SetStatusText(“You
selected: %s” % mypath)

dlg.Destroy()

This is to allow the user to open/choose a logfile from the UI. This has got to be one of the most common
pieces of code a person will need but I have been having real trouble
find some standard pieces of code to do this.

Thanks in advance!

matt d wrote:

    To do what? Create the button? Manage it's layout size and/or
    position? Bind the event handler to the button's event? There are many
    examples of all of these in the demo, samples and the various examples
    on the wiki and elsewhere on the internet.

Yes i have seen the examples but i having a hard time putting it
together with what I already have. Yes again I need to create the
button, pin it to the grid i already have, and make it open the
wxFileDialog, in order to allow me to choose the file which my logger
will write to.

A button is just another kind of widget and because of the class hierarchy ("inheritance" in object oriented programming lingo) it shares a lot of functionality with all the other widget types, including the wx.TextCtrl and wx.StaticText classes that you are already using. In fact, the wx.Button's constructor is almost the same as wx.TextCtrl's. So to create a button object you can just do something like this:

     btn = wx.Button(self, -1, "Click me")

Since it is just another widget and the sizer knows how to manage layout for widgets, then you add it to the sizer exactly the same way:

     sizer.Add(btn, pos=(row,col))

To bind an event handler to the action of the user clicking the button then you use the Bind method. Looking at the docs for wxButton will show you that the event binder you should use is EVT_BUTTON, so the code will look something like this:

     btn.Bind(wx.EVT_BUTTON, self.openfile)

or this would work too, and is another style shown in examples:

     self.Bind(wx.EVT_BUTTON, self.openfile, btn)

The differences between them are subtle and probably not something you want to worry about until you get more familiar with wxPython.

If you haven't already read it then I recommend the ZetCode tutorial at wxPython tutorial - Python GUI programming in wxPython. It is a good introduction to the basics and how they work together. If you want something more substantial then there are The Books: Redirecting...

···

--
Robin Dunn
Software Craftsman

Right so with:
btn = wx.Button(self, -1, “Click me”)
sizer.Add(btn, pos=(7,2))

I can pin the button to where i want.

but as soon as i add this:
btn.Bind(wx.EVT_BUTTON, self.openfile)

I the program bails with this:
AttributeError: ‘TrafficPane’ object has no attribute ‘openfile’

And if I try to add this:

def openfile(self, event):
dlg = wx.FileDialog(self, “Choose a file”, os.getcwd(), “”, “.”, wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
mypath = os.path.basename(path)
self.SetStatusText(“You selected: %s” % mypath)

dlg.Destroy()

or what Yoriz gave; me or anything like i, the whole panel layout gets messed up.
so i have the button just having a very hard time getting the click event to start the wxFileDialog
Thanks guys. (please excuse me if I am being dense here)

or what Yoriz gave; me or anything like i, the whole panel layout gets
messed up.
so i have the button just having a very hard time getting the click event to
start the wxFileDialog

Sounds like this is a job for:
http://wiki.wxpython.org/MakingSampleApps

....

so i have the button just having a very hard time getting the click event to start the wxFileDialog
Thanks guys. (please excuse me if I am being dense here)

Most (or maybe just a few, me definitely) of us have been there, so don't worry.

From above it is difficult to say what is going on.

It could be indentation, it could ......, you are better off attaching code or using something like github gist to show snippets.

I tried the sized_controls about 2 years ago and I do most of my stuff using them as they use the sizers automagically without me having to code it again and again and as a freebie you get platform specific "HIG" compliance.

Attached is a bit of code to get you started with it, you can just run it to see how it looks.

A few tips:
- use the wxPython demo to look how different widgets are used
- the wxPython Phoenix project documenation is also a good source (but it is work in progress and applies to the Phoenix project - see wiki and wxPython API Documentation — wxPython Phoenix 4.2.3a1 documentation)

Werner

traffic_pane_withsizedc.py (1.61 KB)

···

On 20/06/2013 04:20, matt d wrote:

Very good idea. but OMG i can not find an easy way to run some small python code so I can look at the GUI i am writing!?? What am i missing here. i was up to 3am this morning looking for some sort of an IDE or (better IMO) just a way to run my simple .py file from the interpreter. Can you please tell me how to do this so i can test faster?
Thanks!

···

On Wednesday, June 19, 2013 10:54:29 PM UTC-4, Che M wrote:

or what Yoriz gave; me or anything like i, the whole panel layout gets

messed up.

so i have the button just having a very hard time getting the click event to

start the wxFileDialog

Sounds like this is a job for:

http://wiki.wxpython.org/MakingSampleApps

Hey, thanks. Can you please tell me the best way to test my code. I would like to be able to experiment faster by just writing the code and then running the .py file in the interpreter. Then I could see how the layout of the GUI is going even if i doesn’t have the full functionality. Or do I need some sort of IDE or what? Thanks!

···

On Wednesday, June 19, 2013 5:24:31 PM UTC-4, Yoriz wrote:

I’ve cleared out a lot of code to make a small runable snippet of your code with a button added that opens a file dialog.

Hi,

Very good idea. but OMG i can not find an easy way to run some small python code so I can look at the GUI i am writing!?? What am i missing here. i was up to 3am this morning looking for some sort of an IDE or (better IMO) just a way to run my simple .py file from the interpreter. Can you please tell me how to do this so i can test faster?

I use WingIDE, so the script I attached to the last post I would just click on the run button, what I like with Wing is that if an error occurs it stops on the exception and you are in the debugger and can inspect what is going on.

If you want to run it just in the interpreter then just do:

python.exe traffic_pane_withsizedc.py

In both cases the code below "if __name__ == '__main__':" is executed.

Werner

···

On 20/06/2013 13:20, matt d wrote:

i have attached the whole file. its not too long. hope this is not to presumputious but if you could have a look a tell me what you think? THanks!

op25_traffic_pane.py (9.09 KB)

···

On Thursday, June 20, 2013 2:52:52 AM UTC-4, werner wrote:

On 20/06/2013 04:20, matt d wrote:

so i have the button just having a very hard time getting the click
event to start the wxFileDialog

Thanks guys. (please excuse me if I am being dense here)

Most (or maybe just a few, me definitely) of us have been there, so
don’t worry.

From above it is difficult to say what is going on.

It could be indentation, it could …, you are better off attaching
code or using something like github gist to show snippets.

Hi Matt,

Not too big but for the next time make sure not to have dependencies, e.g. I have no use of "gnuradio.gr.gr_threading" so won't spend the time figure out where to get it from and how to install it and .......

Anyhow, attached I just commented that stuff out.

Hope this helps.

Werner

op25_traffic_pane.py (8.57 KB)

On Thu, Jun 20, 2013 at 4:27 AM, matt d

Hey, thanks. Can you please tell me the best way to test my code. I would
like to be able to experiment faster by just writing the code and then
running the .py file in the interpreter.

IDE's can be great, but yes, you really should know how to simply run
you code in the interpreter -- and it's realy easy!

In Windows, Linux, or OS-X, all you need is a console (sometimes
called a "DOS box" in windows). At the command line, cd to the
directory where your code is:

cd the\path\to\my_code_dir

the you should be able to run your file:

python my_script.py

if the system can't find "python" then you need to set your PATH to
where it is installed -- I THINK that the Windows installer does this
for you, but if not, you need to edit your PATH and add something
like:

c:\python27\bin

(sorry not on Windows right now) google for how to do that if you don't know.)

Then I could see how the layout of
the GUI is going even if i doesn't have the full functionality.

for wxPython, I almost always put some simple test start-up code in my
modules -- so a module that defines a new type of panel might have:

import wx

class MyPanel(wx.Panel):
  ...a bunch of code here...

then at the bottom:

(untested)
if __name__ == "__main__":
    app = wx.App(False)
    # you want False, so that errors go to the console...

    f = wx.Frame(None)
    p = MyPanel(f)

    f.Show()
    app.MainLoop()

This should give you enough to test out your Panel, how it lays out,
responds to re-sizing, etc.

Note that if it's hard to have your Panel run by itself like this,
then you've probably got overly-coupled code, and want to re-factor!

See:

for lots of small examples.

-Chris

  Or do I

···

need some sort of IDE or what? Thanks!

--
You received this message because you are subscribed to the Google Groups
"wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Hi Matt,

op25_traffic_pane.py (7.51 KB)

···

On Thursday, June 20, 2013 10:19:15 AM UTC-5, matt d wrote:

On Thursday, June 20, 2013 2:52:52 AM UTC-4, werner wrote:

On 20/06/2013 04:20, matt d wrote:

so i have the button just having a very hard time getting the click
event to start the wxFileDialog

Thanks guys. (please excuse me if I am being dense here)

Most (or maybe just a few, me definitely) of us have been there, so
don’t worry.

From above it is difficult to say what is going on.

It could be indentation, it could …, you are better off attaching
code or using something like github gist to show snippets.

i have attached the whole file. its not too long. hope this is not to presumputious but if you could have a look a tell me what you think? THanks!

I fixed it too, but Werner beat me. Oh well, I spent some time refactoring the code a bit. Anyway, here are some links about dialogs:

Hi Chris,

···

On Thursday, June 20, 2013 10:49:53 AM UTC-5, Chris Barker - NOAA Federal wrote:

On Thu, Jun 20, 2013 at 4:27 AM, matt d

Hey, thanks. Can you please tell me the best way to test my code. I would

like to be able to experiment faster by just writing the code and then

running the .py file in the interpreter.

IDE’s can be great, but yes, you really should know how to simply run

you code in the interpreter – and it’s realy easy!

In Windows, Linux, or OS-X, all you need is a console (sometimes

called a “DOS box” in windows). At the command line, cd to the

directory where your code is:

cd the\path\to\my_code_dir

the you should be able to run your file:

python my_script.py

if the system can’t find “python” then you need to set your PATH to

where it is installed – I THINK that the Windows installer does this

for you, but if not, you need to edit your PATH and add something

like:

c:\python27\bin

Actually, I recommend just adding Python to the Windows path so you don’t have to type the full path all the time. However, here is the Window’s path: c:\Python26\python.exe

For the OP, here is some information for making the use of Python on Windows easier:

I also like having the PyWin32 package available on Windows if I plan to do anything to the Windows OS.

  • Mike

As long as you have allowed the pywin32 installer to do its work, it
will have registered the .py and .pyw extensions automatically, so
all you have to type is the file name:
my_script.py
Even better, by adding .py and .pyw to the PATHEXT environment
variable, you don’t even need the extension:
my_script

···

Mike Driscoll wrote:

    if the

system can’t find “python” then you need to set your PATH to

    where it is installed -- I THINK that the Windows installer does

this

    for you, but if not, you need to edit your PATH and add

something

    like:




    c:\python27\bin
    Actually, I recommend just adding Python to the Windows path so

you don’t have to type the full path all the time. However, here
is the Window’s path: c:\Python26\python.exe

-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

Whats wrong with the snippet i posted hours ago?
Mike i skimmed over your code and noticed an error in your refactoring, the same text ctrl is set in fields dict over and over instead of the newly created one, i done a similar refactoring in the code i posted and just included adding the field into the fields dict in my method createTextCtrl.

···

On Wednesday, June 19, 2013 3:11:01 PM UTC+1, matt d wrote:

Hello all!

I have a panel:

class TrafficPane(wx.Panel):

Initializer

the class constructor

def init(self, parent, msgq):

wx.Panel.init(self,
parent)

self.msgq = msgq

open a file named “logfile.txt”

in “a” append mode;

creates file if it doesn’t exist.

self.logfile =
open(‘logfile.txt’, ‘a’)

#layout of the panel. 10 px gap
on each side of TextCtrls. panel is a grid,

#texctrls and lables are placed
at grid positions like (1,1), (2,1) etc.

sizer =
wx.GridBagSizer(hgap=10, vgap=10)

defines a dictionary ({} = empty

dictionary), to hold the text control values

self.fields = {}

#TextCtrl recipe:

#creates the first label static text
on gui panel

label = wx.StaticText(self, -1,
“DUID:”)

#position on the gui panel
grid, top left

sizer.Add(label, pos=(1,1))

#create the textCtrl field,
give it a size, make it read-only

field = wx.TextCtrl(self, -1,
“”, size=(144, -1), style=wx.TE_READONLY)

#sticks TextCrtl to grid right
of label

sizer.Add(field, pos=(1,2))

#add the field for this
TextCtrl to the dictionary

self.fields[“duid”] =
field;

There are 8 more TextCtrls like this
one. I need to put an event button under the TextCtrls that will
trigger the wxFileDialog something like:

def openfile(self, event):

dlg = wx.FileDialog(self,
“Choose a file”, os.getcwd(), “”, “.”,
wx.OPEN)

if dlg.ShowModal() == wx.ID_OK:

path = dlg.GetPath()

mypath =
os.path.basename(path)

self.SetStatusText(“You
selected: %s” % mypath)

dlg.Destroy()

This is to allow the user to open/choose a logfile from the UI. This has got to be one of the most common
pieces of code a person will need but I have been having real trouble
find some standard pieces of code to do this.

Thanks in advance!

matt d wrote:

i have attached the whole file. its not too long. hope this is not to
presumputious but if you could have a look a tell me what you think?

In the spirit of the Python philosophy of "don't repeat yourself", I
would replace that long repetitive section that creates the fields with
a data-driven loop like this:

        data = (
            ( "DUID:", "duid", (1,1) ),
            ( "NAC:", "nac", (2,1) ),
            ( "Source:", "source", (3,1) ),
            ( "Destination:", "dest", (4,1) ),
            ( "MFID:", "mfid", (1,4) ),
            ( "ALGID:", "algid", (2,4) ),
            ( "KID:", "kid", (3,4) ),
            ( "MI:", "mi", (4,4) ),
            ( "TGID:", "tgid", (5,4) )
        )

        for title, fldname, labelpos in data:
            label = wx.StaticText(self, -1, title)
            sizer.Add(label, pos=labelpos)
            txtpos = (labelpos[0], labelpos[1]+1)
            field = wx.TextCtrl( self, -1, "", size=(144,-1),
style=wx.TE_READONLY)
            sizer.Add(field, pos=txtpos)
            self.fields[fldname] = field

One advantage of this is that it will be easier to add buttons, since
you only have to add them in one place and modify the data structure.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Whats wrong with the snippet i posted hours ago?

I didn’t look at every single example…I just wanted to take a whack at it.

Mike i skimmed over your code and noticed an error in your refactoring, the same text ctrl is set in fields dict over and over instead of the newly created one, i done a similar refactoring in the code i posted and just included adding the field into the fields dict in my method createTextCtrl.

Oops…oh well. I was actually thinking about doing something like what Tim proposes, but I didn’t want to spend the extra cycles to actually put together an example.

  • Mike
···

On Thursday, June 20, 2013 11:30:25 AM UTC-5, Yoriz wrote: