[newbie] advice and comment wanted on first tkinter program


J

Jean Dupont

Dear all,
I made a simple gui with tkinter. I can imagine there are things which I
did which are "not optimal". So what I ask is to comment on my code
preferable with snippets of code which show how to do improve my code.
#!/usr/bin/env python
import Tkinter
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(26,GPIO.OUT)
GPIO.setup(24,GPIO.OUT)
#hardware : connect 2 leds:
#board-pin 26 on/off led; control with buttons
#board-pin 24 led with pwm dimming and frequency; control via sliders
top = Tkinter.Tk()
top.geometry("600x400+310+290")
var1 = DoubleVar()
var2 = DoubleVar()
i=0
p=GPIO.PWM(24,1)
p.start(50)
def btn_on_cmd():
text3.configure(bg = "#00FF00")
text3.delete(0.1,END)
text3.insert("0.1","ON ")
GPIo_Output(26,True)
def btn_off_cmd():
text3.configure(bg = "#FF4000")
text3.delete(0.1,END)
text3.insert("0.1","OFF")
GPIo_Output(26, False)
def timer0():
global i
i=i+1
text1.delete(0.1,END)
text1.insert(4.2,"Timer: " + str(i))
label1.configure(text=time.strftime("%H:%M:%S"))
top.after(1000, timer0)
def Set_PWM(var1):
DC = float(var1)
p.ChangeDutyCycle(DC)
def Set_FREQ(var2):
FR = float(var2)
p.ChangeFrequency(FR)
btn_on = Button(top, text ="On", command = btn_on_cmd)
btn_on.place(x=10,y=100)
btn_off = Button(top, text ="Off", command = btn_off_cmd)
btn_off.place(x=100,y=100)
text1 =Text(top, bg = "#009BFF", font=("Helvetica",14), height = 1, width
= 15)
text1.place(x=5,y=5)
text3=Text(top, bg = "red", font=("Helvetica",12),height = 1, width = 4)
text3.place(x=60,y=60)
label1 = Label(top,relief=RAISED,bg =
"#EFF980",font=("Helvetica",14),height = 1, width = 15)
label1.place(x=5,y=350)
label2= Label(top,relief=RAISED,bg =
"#BFBFBF",font=("Helvetica",10),height = 1, text= "Freq (Hz)")
label2.place(x=420,y=320)
label3= Label(top,relief=RAISED,bg =
"#BFBFBF",font=("Helvetica",10),height = 1, text= "DC %")
label3.place(x=520,y=320)
slider1 = Scale(top,variable = var1,length = 300,resolution = 1,command =
Set_PWM)
slider1 = Scale(top,variable = var1,length = 300,resolution = 1,command = Set_PWM)
slider1.place(x=500,y=5)
slider1.set(50)
slider2 = Scale(top,variable = var2,length = 300,from_= 0.1, to = 50,resolution = 0.1,command = Set_FREQ)
slider2.place(x=400,y=5)
slider2.set(2)
timer0()
top.mainloop()
GPIO.cleanup()


thanks in advance
jean
 
Ad

Advertisements

P

Peter Otten

Jean said:
Dear all,
I made a simple gui with tkinter. I can imagine there are things which I
did which are "not optimal". So what I ask is to comment on my code
preferable with snippets of code which show how to do improve my code.
#!/usr/bin/env python
import Tkinter
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(26,GPIO.OUT)
GPIO.setup(24,GPIO.OUT)
#hardware : connect 2 leds:
#board-pin 26 on/off led; control with buttons
#board-pin 24 led with pwm dimming and frequency; control via sliders
top = Tkinter.Tk()
top.geometry("600x400+310+290")
var1 = DoubleVar()
var2 = DoubleVar()
i=0
p=GPIO.PWM(24,1)
p.start(50)
def btn_on_cmd():
text3.configure(bg = "#00FF00")
text3.delete(0.1,END)
text3.insert("0.1","ON ")
GPIo_Output(26,True)
def btn_off_cmd():
text3.configure(bg = "#FF4000")
text3.delete(0.1,END)
text3.insert("0.1","OFF")
GPIo_Output(26, False)
def timer0():
global i
i=i+1
text1.delete(0.1,END)
text1.insert(4.2,"Timer: " + str(i))
label1.configure(text=time.strftime("%H:%M:%S"))
top.after(1000, timer0)
def Set_PWM(var1):
DC = float(var1)
p.ChangeDutyCycle(DC)
def Set_FREQ(var2):
FR = float(var2)
p.ChangeFrequency(FR)
btn_on = Button(top, text ="On", command = btn_on_cmd)
btn_on.place(x=10,y=100)
btn_off = Button(top, text ="Off", command = btn_off_cmd)
btn_off.place(x=100,y=100)
text1 =Text(top, bg = "#009BFF", font=("Helvetica",14), height = 1, width
= 15)
text1.place(x=5,y=5)
text3=Text(top, bg = "red", font=("Helvetica",12),height = 1, width = 4)
text3.place(x=60,y=60)
label1 = Label(top,relief=RAISED,bg =
"#EFF980",font=("Helvetica",14),height = 1, width = 15)
label1.place(x=5,y=350)
label2= Label(top,relief=RAISED,bg =
"#BFBFBF",font=("Helvetica",10),height = 1, text= "Freq (Hz)")
label2.place(x=420,y=320)
label3= Label(top,relief=RAISED,bg =
"#BFBFBF",font=("Helvetica",10),height = 1, text= "DC %")
label3.place(x=520,y=320)
slider1 = Scale(top,variable = var1,length = 300,resolution = 1,command =
Set_PWM)
slider1 = Scale(top,variable = var1,length = 300,resolution = 1,command =
Set_PWM) slider1.place(x=500,y=5)
slider1.set(50)
slider2 = Scale(top,variable = var2,length = 300,from_= 0.1, to =
50,resolution = 0.1,command = Set_FREQ) slider2.place(x=400,y=5)
slider2.set(2)
timer0()
top.mainloop()
GPIO.cleanup()


thanks in advance
jean

First and foremost a program has to do what the author wants it to do.
Everything else is secondary. You are likely to have such a program on your
machine, so congrats :)

However, the version you posted does not run, probably because you started
to replace

from Tkinter import *
top = Tk()
....
var1 = DoubleVar()

with the -- better --

import Tkinter
top = Tkinter.Tk()
....

but stopped too early, so that the line

var1 = DoubleVar

will raise a NameError. The fix is mechanical: run the program, go to the
line with the NameError and add the 'Tkinter.' prefix.

Once you have done that you should take the time to find good variable
names. var1? I have no idea what value that could hold until I've read the
whole program. That's feasible here, but program size may grow over time,
and can you still tell me what var1 means next week? I recommend names that
reflect the problem domain, e. g. `var_dutycycle` or just `dutycycle`.

Next you should consider grouping the code by topic -- not necessarily into
functions; having a section that does the setup for the dutycycle data and
widgets and one for the time etc., visually separated by one or two empty
lines should be sufficient.

If you're ambitious you should read up on the grid layout manager. I allows
widget size to change depending on the window size.

The Text widget can be used to write whole Editors (like IDLE) -- it does no
harm here, but seems a bit heavyweight for just an On/Off display. I would
go with a Label or Entry.

What does a red widget with no text mean, by the way? On, off, or undefined?
Personally, I like to start with a defined state. An easy way to achieve
this is to call

button_off_cmd() # or button_on_cmd()

manually before your program enters the mainloop() -- just like you did with
timer0().

PS: An easy way to get an idea of what a script does is to run it. I'd guess
that by keeping the Rasperry-Pi-specific code in you are reducing the number
of readers who can do that by a few orders of magnitude. I managed to get it
to run with the following ad-hoc changes:

$ diff -u raspberry_orig.py raspberry_mock.py
--- raspberry_orig.py 2014-01-17 16:10:20.843334832 +0100
+++ raspberry_mock.py 2014-01-17 16:10:58.970855503 +0100
@@ -1,7 +1,36 @@
#!/usr/bin/env python
import Tkinter
+from Tkinter import *
import time
-import RPi.GPIO as GPIO
+
+try:
+ import RPi.GPIO as GPIO
+except ImportError:
+ class Name(str):
+ def __repr__(self):
+ return self
+
+ class GPIO:
+ def __init__(self, prefix):
+ self.prefix = prefix
+ def __getattr__(self, name):
+ if name in ["BOARD", "OUT"]:
+ return Name(name)
+ if name == "PWM":
+ return GPIO("PWM")
+ if name == "__call__":
+ def c(*args):
+ print "Initializing {}{}".format(self.prefix, args)
+ return self
+ return c
+ def f(*args):
+ print "Calling {}.{}{}".format(self.prefix, name, args)
+ return f
+
+ GPIO = GPIO("GPIO")
+
+
+
GPIO.setmode(GPIO.BOARD)
GPIO.setup(26,GPIO.OUT)
GPIO.setup(24,GPIO.OUT)
 
T

Terry Reedy

Dear all,
I made a simple gui with tkinter. I can imagine there are things which I
did which are "not optimal". So what I ask is to comment on my code
preferable with snippets of code which show how to do improve my code.
#!/usr/bin/env python
import Tkinter

1. import Tkinter as tk

Besides saving a bit of writing and reading time later, this makes any
future conversion to 3.x easier.

import tkinter as tk

2. add a few spaces to demarcate blocks of code.
import time
import RPi.GPIO as GPIO

2. add a few spaces to demarcate blocks of code, such as here
GPIO.setmode(GPIO.BOARD)
GPIO.setup(26,GPIO.OUT)
GPIO.setup(24,GPIO.OUT)
#hardware : connect 2 leds:
#board-pin 26 on/off led; control with buttons
#board-pin 24 led with pwm dimming and frequency; control via sliders

and here
top = Tkinter.Tk()
top.geometry("600x400+310+290")

This looks strange somehow, but if it works...

label1 = Label(top,relief=RAISED,bg =
"#EFF980",font=("Helvetica",14),height = 1, width = 15)

In calls, put spaces after , but not before and after =.
For other suggestions, see
http://www.python.org/dev/peps/pep-0008/

I suspect that the above is one line in your code and the bad wrapping a
result of mis-spacing. The following is also one line, but easer to read
as spaces separate argument chunks

label1 = Label(top, relief=RAISED, bg="#EFF980", font=("Helvetica",14),
height=1, width=15)

and the wrapping, if any, does not break up an arg chunk.

Some people advocate defining an App class, but Tk and tkinter, even
though object method based, allow the straightforward imperative style
you have used.

I agree with Peter: "First and foremost a program has to do what the
author wants it to do. Everything else is secondary." But a bit of
styling will make reading and changing easier.
 
J

Jean Dupont

Op vrijdag 17 januari 2014 22:40:42 UTC+1 schreef Terry Reedy:
1. import Tkinter as tk



Besides saving a bit of writing and reading time later, this makes any

future conversion to 3.x easier.



import tkinter as tk



2. add a few spaces to demarcate blocks of code.







2. add a few spaces to demarcate blocks of code, such as here








and here







This looks strange somehow, but if it works...









In calls, put spaces after , but not before and after =.

For other suggestions, see

http://www.python.org/dev/peps/pep-0008/



I suspect that the above is one line in your code and the bad wrapping a

result of mis-spacing. The following is also one line, but easer to read

as spaces separate argument chunks



label1 = Label(top, relief=RAISED, bg="#EFF980", font=("Helvetica",14),

height=1, width=15)



and the wrapping, if any, does not break up an arg chunk.



Some people advocate defining an App class, but Tk and tkinter, even

though object method based, allow the straightforward imperative style

you have used.



I agree with Peter: "First and foremost a program has to do what the

author wants it to do. Everything else is secondary." But a bit of

styling will make reading and changing easier.

Thanks Peter and Terry Jan for the useful suggestions. One thing which I find a bit weird: when asking for Python-help concerning raspberry pi code orproblems, a lot of people don't seem to be interested in helping out, that's of course their choice, but maybe they don't seem to be aware the raspberry pi is often the motivation for starting to learn to program in Python. And as such such a reaction is a bit disappointing.

kind regards,
jean
 
O

Oscar Benjamin

Thanks Peter and Terry Jan for the useful suggestions. One thing which I find a bit weird: when asking for Python-help concerning raspberry pi code or problems, a lot of people don't seem to be interested in helping out, that's of course their choice, but maybe they don't seem to be aware the raspberry pi is often the motivation for starting to learn to program in Python.. And as such such a reaction is a bit disappointing.

Hi Jean,

What makes you say that? Did you previously ask questions about
Rasberry Pi code on this list?

If you did I wouldn't have answered those questions because I've never
used a Raspberry Pi and know nothing about them (except that they
encourage using Python somehow). I think that there's actually a list
that is specifically for Raspberry Pi Python questions that might be
more helpful although I don't know what it is...


Oscar
 
M

Mark Lawrence

Hi Jean,

What makes you say that? Did you previously ask questions about
Rasberry Pi code on this list?

If you did I wouldn't have answered those questions because I've never
used a Raspberry Pi and know nothing about them (except that they
encourage using Python somehow). I think that there's actually a list
that is specifically for Raspberry Pi Python questions that might be
more helpful although I don't know what it is...


Oscar

As Python is meant to be cross platform i think it's pretty much
irrelevant that Raspberry Pi is mentioned. It's far more likely that
people don't respond as questions are asked about specific libraries
which they haven't used.

Neither does it help when considering Jean's last post that the final
paragraph shows as one line in Thunderbird on Windows and over 60% is
simply blank lines. No guesses as to how he's posting.
 
Ad

Advertisements

D

Dennis Lee Bieber

Thanks Peter and Terry Jan for the useful suggestions. One thing which I find a bit weird: when asking for Python-help concerning raspberry pi code or problems, a lot of people don't seem to be interested in helping out, that's of course their choice, but maybe they don't seem to be aware the raspberry pi is often the motivation for starting to learn to program in Python. And as such such a reaction is a bit disappointing.

There is a difference between learning Python ON a Raspberry-Pi, and
learning the Raspberry-Pi with Python.

R-Pi specific libraries or code aren't things every Python user would
have experience with; asking in the R-Pi newsgroup -- comp.sys.raspberry-pi
-- would at least focus the matter to people with experience or interest in
the R-Pi.

Granted, that may require one to obtain a proper Usenet news-client and
access to a news server carrying the group; rather than the corrupting
influence of Google Groups (I haven't looked to see if GG has access to it;
but GG makes a trash out of messages that gateway out to the real world).
 
G

Grawburg

The Raspberry Pi is exactly what got me started with Python. I'm at medium-sized science museum and used the Pi, Python, & tkinter to introduce kids to programming & Linux this past summer.

Jean, feel free to contact me off-line for my experience with all three.


Brian Grawburg
Wilson, NC


-----Original Message-----
From: "Oscar Benjamin" <[email protected]>
To: "Jean Dupont" <[email protected]>
Cc: "Python List" <[email protected]>
Date: 01/18/14 10:13 AM
Subject: Re: [newbie] advice and comment wanted on first tkinter program

Thanks Peter and Terry Jan for the useful suggestions. One thing which I find a bit weird: when asking for Python-help concerning raspberry pi code or problems, a lot of people don't seem to be interested in helping out, that's of course their choice, but maybe they don't seem to be aware the raspberry pi is often the motivation for starting to learn to program in Python. And as such such a reaction is a bit disappointing.

Hi Jean,

What makes you say that? Did you previously ask questions about
Rasberry Pi code on this list?

If you did I wouldn't have answered those questions because I've never
used a Raspberry Pi and know nothing about them (except that they
encourage using Python somehow). I think that there's actually a list
that is specifically for Raspberry Pi Python questions that might be
more helpful although I don't know what it is...


Oscar
 
D

Dennis Lee Bieber

Talking to myself, again...

There is a difference between learning Python ON a Raspberry-Pi, and
learning the Raspberry-Pi with Python.

R-Pi specific libraries or code aren't things every Python user would
have experience with; asking in the R-Pi newsgroup -- comp.sys.raspberry-pi
-- would at least focus the matter to people with experience or interest in
the R-Pi.
I do need to moderate this somewhat (I haven't looked at the full
thread). For purely Python matters, this is likely a good spot -- Sorry if
I sounded overly harsh.

Unfortunately, when it comes to tkinter/Tk -- my one program was a
decade ago, relying upon a no doubt now out-of-print book, and took a long
time to get it working properly... And it was just a single window/form
with a mass of file and directory requesters (used to set up a run
configuration for a test station -- pick the release version, where the
executables to install on the test hardware were located, etc.).

All that to lead into: I tend to skip posts that mention tkinter.
 
J

Jean Dupont

Op zaterdag 18 januari 2014 16:12:41 UTC+1 schreef Oscar Benjamin:
Hi Jean,
What makes you say that? Did you previously ask questions about
Rasberry Pi code on this list?
It was not about code but about python-coding in IDLE (that's the default
on raspbian):
I started a thread "[newbie] starting geany from within idle does not
work" both here and in the raspberry pi forum. I just wondered why I never
got an answer concerning that topic.
If you did I wouldn't have answered those questions because I've never
used a Raspberry Pi and know nothing about them (except that they
encourage using Python somehow). I think that there's actually a list
that is specifically for Raspberry Pi Python questions that might be
more helpful although I don't know what it is...
Here is the url to that forum

http://www.raspberrypi.org/forum/

kind regards,
jean
 
C

Chris Angelico

I started a thread "[newbie] starting geany from within idle does not
work" both here and in the raspberry pi forum. I just wondered why I never
got an answer concerning that topic.

I saw that thread. It looked like a R-Pi problem, not a Python one, so
I didn't respond because I don't have an R-Pi. If you get no response
on the R-Pi forum, you might want to see if you can duplicate the
issue on a desktop computer - preferably on Win/Mac/Lin, as those are
the platforms most people use. That, with exact steps to repro (which
it looks like you gave for the R-Pi, though again I can't verify),
would get some interest.

ChrisA
 
Ad

Advertisements

J

Jean Dupont

Op maandag 20 januari 2014 07:24:31 UTC+1 schreef Chris Angelico:
I started a thread "[newbie] starting geany from within idle does not
work" both here and in the raspberry pi forum. I just wondered why I never
got an answer concerning that topic.
I saw that thread. It looked like a R-Pi problem, not a Python one, so
I didn't respond because I don't have an R-Pi. If you get no response
on the R-Pi forum, you might want to see if you can duplicate the
issue on a desktop computer - preferably on Win/Mac/Lin, as those are
the platforms most people use. That, with exact steps to repro (which
it looks like you gave for the R-Pi, though again I can't verify),
would get some interest.
I did try to do the same on my linux desktop computer, but the problem is,
it has another desktop environment (KDE4). In the rpi-environment it is
possible
(but it doesn't work) to change the default IDLE-editor by right-clicking
the idle-icon and choosing geany in stead of leafpad, however the same
can't be done
in KDE4, I hoped to find a similar setting once running IDLE in
Options-->Configure IDLE, but nothing there neither. I also looked
unsuccessfuly in the .idlerc-directory for a config-file. Hence my initial
question.

kind regards,
jean
 
D

Dave Angel

Jean Dupont said:
Op maandag 20 januari 2014 07:24:31 UTC+1 schreef Chris Angelico:
I started a thread "[newbie] starting geany from within idle does not
work"

I did try to do the same on my linux desktop computer, but the problem is,
it has another desktop environment (KDE4). In the rpi-environment it is
possible
(but it doesn't work) to change the default IDLE-editor by right-clicking
the idle-icon and choosing geany in stead of leafpad, however the same
can't be done
in KDE4, I hoped to find a similar setting once running IDLE in
Options-->Configure IDLE, but nothing there neither. I also looked
unsuccessfuly in the .idlerc-directory for a config-file. Hence my initial
question.

What does idle offer that Geary does not? Why not just run Geary
from your terminal prompt?
 
J

Jean Dupont

Op maandag 20 januari 2014 10:17:15 UTC+1 schreef Alister:
Op zaterdag 18 januari 2014 16:12:41 UTC+1 schreef Oscar Benjamin:
Thanks Peter and Terry Jan for the useful suggestions. One thing
which I
find a bit weird: when asking for Python-help concerning raspberry pi
code
or problems, a lot of people don't seem to be interested in helping
out,
that's of course their choice, but maybe they don't seem to be aware
the raspberry pi is often the motivation for starting to learn to
program in
Python. And as such such a reaction is a bit disappointing.
Hi Jean,
What makes you say that? Did you previously ask questions about
Rasberry Pi code on this list?
It was not about code but about python-coding in IDLE (that's the
default on raspbian):
I started a thread "[newbie] starting geany from within idle does not
work" both here and in the raspberry pi forum. I just wondered why I
never got an answer concerning that topic.
If you did I wouldn't have answered those questions because I've never
used a Raspberry Pi and know nothing about them (except that they
encourage using Python somehow). I think that there's actually a list
that is specifically for Raspberry Pi Python questions that might be
more helpful although I don't know what it is...
Here is the url to that forum

http://www.raspberrypi.org/forum/

kind regards,
jean

Personally use Geany stand alone and not under idle, pressing F5 should
save & run the code you are currently editing. Would running under idle
give any other benefits?
I don't know yet, but I just wanted to try out which of the following three I'd like best:
1. idle+leafpad
2. idle+geany
3. plain geany

It's normal for a newbie to start with (1) as that is the default on raspbian,
however I still don't understand why (2) does not work...

kind regards,
jean
 
J

Jean Dupont

Op woensdag 22 januari 2014 16:43:21 UTC+1 schreef Alister:
When I play with my Pi I tend to use another computer for all my editing
(sshfs is a quick & easy way for me to mount the necessary parts of the
PI file system so I don't have to keep transferring files)
Thanks for the suggestion, I'm going to try it out

kind regards,
jean
 
Ad

Advertisements

J

Jean Dupont

Op woensdag 22 januari 2014 15:45:53 UTC+1 schreef Jean Dupont:
Op maandag 20 januari 2014 10:17:15 UTC+1 schreef Alister:
Op zaterdag 18 januari 2014 16:12:41 UTC+1 schreef Oscar Benjamin:

Thanks Peter and Terry Jan for the useful suggestions. One thing
which I
find a bit weird: when asking for Python-help concerning raspberry pi
code
or problems, a lot of people don't seem to be interested in helping
out,
that's of course their choice, but maybe they don't seem to be aware
the raspberry pi is often the motivation for starting to learn to
program in
Python. And as such such a reaction is a bit disappointing.
Hi Jean,
What makes you say that? Did you previously ask questions about
Rasberry Pi code on this list?
It was not about code but about python-coding in IDLE (that's the
default on raspbian):
I started a thread "[newbie] starting geany from within idle does not
work" both here and in the raspberry pi forum. I just wondered why I
never got an answer concerning that topic.

If you did I wouldn't have answered those questions because I've never
used a Raspberry Pi and know nothing about them (except that they
encourage using Python somehow). I think that there's actually a list
that is specifically for Raspberry Pi Python questions that might be
more helpful although I don't know what it is...
Here is the url to that forum

http://www.raspberrypi.org/forum/

kind regards,
jean

Personally use Geany stand alone and not under idle, pressing F5 should
save & run the code you are currently editing. Would running under idle
give any other benefits?
I don't know yet, but I just wanted to try out which of the following three I'd like best:
1. idle+leafpad
2. idle+geany
3. plain geany

It's normal for a newbie to start with (1) as that is the default on raspbian,
however I still don't understand why (2) does not work...
I finally found out where I was wrong: leafpad is _not_ the default choice
in IDLE, IDLE has its own built in editor and IDLE does not allow to use
another editor. The confusion stemmed from the properties I got when right
clicking on the IDLE-icon on the raspbian desktop, which shows "Open with"
and then suggests the default choice is Leafpad and Geany as a second
choice, it has however nothin to do with IDLE as such.

kind regards,
jean
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top