Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Wednesday, January 26, 2022

Python-docx

The amount that I have learned about they python-docx library could fill a book. Fortunately all of that information is still online where I originally found it. For the purposes of closing tabs, here are some selected lessons and links:
In word tables, to set cell sizes and other cell properties it isn't really set up to do it like a person would and set properties by row or column. Most properties are set at the individual cell number, but it's a computer, make it iterate through all the cells in a row and column to get the desired look. https://stackoverflow.com/questions/43051462/python-docx-how-to-set-cell-width-in-tables
Here's the online python-docx docs page about tables. Doesn't fully illuminate the ideosyncracies, mostly a general explainer on how docx is xml and what tables look like in this particular xml. Apparently there are only two table-wide properties, because everything else is cell properties. The table-wide properties are alignment and fixed-width vs auto-width columns: https://python-docx.readthedocs.io/en/latest/dev/analysis/features/table/table-props.html

Wednesday, February 12, 2020

Python hints for gain comparison script

Sources for fixing my bad coding for making the data graphs:

Directly setting the tick labels in matplotlib. Haven't gone here yet but this is apparently not a simple tweak although there is a formula for getting it right: https://stackoverflow.com/questions/11244514/modify-tick-label-text
The .plot() method for matplotlib and how it so nicely allows for multiple lines on the same plot: https://matplotlib.org/api/_as_gen/matplotlib.pyplot.plot.html
Extracting a column from a 2D list. 3 methods: 1) list conprehension, 2) just use numpy 3) zip https://stackoverflow.com/questions/30062429/python-how-to-get-every-first-element-in-2-dimensional-list/30062458
Initializing a list for my x axis values, explained for babies: https://www.science-emergence.com/Articles/How-to-create-a-list-of-numbers-in-python-/
Doing multiplication and division between elements of three arrays: Just use numpy. https://stackoverflow.com/questions/10271484/how-to-perform-element-wise-multiplication-of-two-lists

Thursday, October 27, 2016

Python command line arguments

I needed to be able to pass an argument into my program to allow it to run in two different ways. The syntax of the constructor that I'd simply copied from something else a long time ago is weird. It turns out that these are two different problems. Neither wasn't so bad once I dug into them.

To pass an argument into the program from the command line, just use c-like argc and argv:

http://www.cyberciti.biz/faq/python-command-line-arguments-argv-example/

The constructor is using a pythonic trick of indirectly referencing a function's argument list. It's nothing to do with the command line and isn't specific to constructors:

http://stackoverflow.com/questions/3394835/args-and-kwargs

https://mail.python.org/pipermail/tutor/2006-August/048394.html

https://pythonprogramming.net/styling-gui-bit-using-ttk/

Tuesday, October 25, 2016

python tkinter label 2

Tired of not having the scrollbar that I wanted on my event log window, I finally revisited my earlier searches and figured out why I hadn't been able to get it working the first time and got it working.

The main thing that had confused me was that placing objects in a "Canvas" widget is not the same thing as packing Frames together. It's almost like there is an entirely separate language within Tkinter for Canvasses. Additionally, it takes a while to pick up on the fact that the scrollbar is a separate widget that is not actually a part of the Canvas or any Frame or other object, you simply place it to the side of the Canvas such that it looks related and then you link its position property to the "view" property of the Canvas (there is a vertical view property and a horizontal view property; in my case I am using one scrollbar to control only the vertical view).

The trick to getting the geometry right was to define a Frame of fixed size, put the Canvas and the scrollbar side by side in the Frame such that their edges fill it, then put a Frame in a window on the Canvas and then inside that Frame put a text Label which can expand, which will cause the Frame containing it to expand as needed. (In my case I set the width and wraplength properties of the Label to ensure that it would not expand in the horizontal direction, because I didn't want to have a horizontal scrollbar for my event window, just a vertical scroll bar.) After doing this, the Label is allowed to get as big in the vertical direction as it wants, as in my first implementation. but the amount of text that shows is framed by the size of the window on the Canvas that is holding the interior Frame, and the location of the view of that Frame through the window that is showing on the Canvas is controlled by scrollbar. I did have to define an initial size for the interior Frame which matched the expected size of the viewable canvas area produced by the size of the fixed outside Frame minus the size of the scrollbar, but the size of the inside Frame was not fixed.

The part that I couldn't get right for the longest time is the part where you put the interior Frame in the Canvas. That is because it is not the same mechanism as for the rest of Tkinter, where you are "packing" Frames together inside other Frames. A Canvas is intended to have anything just anywhere on it and allows for overlapping and layering. The interior Frame is inside a "window" of the canvas, and you don't "pack" windows, you "create" them for the canvas. It took forever to get the syntax right for creating the window with the frame inside it and anchoring it where I wanted it. To do it, create a Canvas with an exterior Frame as its root and pack it into the Frame, then create another Frame for the interior frame and use the Canvas.create_window() function which has an argument that links to the frame object that you want to put in the window, a starting coordinate for the location of the window on the canvas, and an anchor geometry argument which I think overrides the coordinate argument. The Label widget can be created and packed into the interior Frame at any time.

Now that I had a window with a Frame inside it that had an expanding Label widget inside it, on a canvas that had a fixed size due to being packed into a nonexpanding Frame next to a scrollbar, I had to link the scrollbar to the viewing area of the window. This requires two things; one that the scrollbar position output is linked to the canvas's yview parameter (why it's the canvas's yview parameter and not the window's, I'm not quite sure), and two that every time the frame expands that the scrollbar's scroll region "size" is adjusted.

To link the scrollbar to the canvas is easy; it's almost as if the creators of Tkinter somehow anticipated that programmers would want to do this and intentionally made the output type of the scrollbar the same type as the inputs for the canvas view function. So it's just a matter of setting the scrollbar to use the canvas's yview as the position that the scrollbar shows its position as, and the canvas's yscrollcommand to be called every time the scrollbar set() function is triggered by the user adjusting the scrollbar. The output of the scrollbar set() function is fed directly into the yscrollcommand function using the following super compact syntax:

Canvas.configure(yscrollcommand=Scrollbar.set)

To make the viewable area that the scrollbar can access change every time that new lines are added to the StringVar for the Label object, the technique is to define something for the callback for the Frame's "Configuration". I.e. if the frame size changes (due to stretching), it is considered a change in configuration and whatever is defined in the Configuration callback gets executed. Normally that stub is empty, but all I have to do is put in some code that sets the "scrollregion" parameter of the canvas to the frame's new size; the size of the scrollbar's scroll region is already linked to that parameter earlier in the setup code so it passes through. Again, the command syntax is super compact (i.e. opaque), but it looks something like this:

Canvas.configure(scrollregion=Canvas.bbox("all"))

The other tricky part was in that I wanted my text to scroll up from the bottom, with old text disappearing from view at the top, with the scrollbar adjusting in size to match the new number of lines but the view remaining anchored at the bottom unless the user began using the scrollbar to see text that had scrolled up. To accomplish this, I added something to the Frame Conguration callback so that each time the frame stretched, the last thing the callback did was manually set the scrollbar's position to the bottom. It actually does this by setting the Canvas's yvivew to the bottom; the scrollbar setting just updates accordingly. The yview position is defined as a fractional value, ranging from 0.0 to 1.0, so this command sets it to 1.0

Canvas.yview_moveto(1.0)

However, this also results in a problem, because for some reason, every time the user grabs the scrollbar and tries to scroll up, it triggers a Configure callback for the frame for some reason, and the user setting the scrollbar position and the callback trying to set it to 1.0 would conflict quite badly. The answer was to look at the frame height every time the Configure callback was called and compare it to a stored previous value; if the frame height hadn't changed then the reason for the callback must not have been due to adding a new line of text, so there is no reason to set the viewing position back to the bottom.

Below is my code where I define the geometry of everything. As before, f is the root frame, and f5 is a frame where my status window will go below four other frames containing other stuff:

f5 = Tkinter.Frame(f, bd=1, relief="groove", width=720,height=100)
# The next line makes sure that the frame does not stretch based on its contents
f5.pack_propagate(0)
f5.pack(anchor="w",padx=10)

# Have to set the canvas width or it defaults to something stupid
self.statuscanvas=Tkinter.Canvas(f5,width=700,height=100)

# Add a scrollbar to f5 which controls the yview of the canvas
self.statusscrollbar=Tkinter.Scrollbar(f5,orient="vertical",command=self.statuscanvas.yview)
self.statuscanvas.configure(yscrollcommand=self.statusscrollbar.set)

# Pack the scrollbar on the right and the canvas on the left inside f5
self.statusscrollbar.pack(side="right",fill="y")
self.statuscanvas.pack(side="left")

# Now make a frame with the status message label in it
f5i = Tkinter.Frame(self.statuscanvas,width=2800,height=100)
self.stattext = Tkinter.StringVar()
self.stattext.set("")
self.status = Tkinter.Label(f5i,textvar=self.stattext, justify="left",anchor="sw",width=900, wraplength=640)
self.status.pack(side="bottom")

# Add the status frame as a window in the canvas
self.statuscanvas.create_window((0,0),window=f5i,anchor="nw")

# Add a callback to the frame so that every time it changes size the scrollbar can be resized
self.statusheight = 0
f5i.bind("",self.scrollbarConfigure)

Here is the code for the callback of the frame inside the canvas that is triggered every time the frame configuration changes (i.e. as a result of a resize due to the frame stretching) so that we can set the scrollbar's size to match the new size of the frame and the scrollbar can scroll the canvas's view over the entire new size of the frame:

def scrollbarConfigure(self,event):
self.statuscanvas.configure(scrollregion=self.statuscanvas.bbox("all"))
if not(event.height == self.statusheight):
self.statuscanvas.yview_moveto(1.0)
self.statusheight = event.height

So, here is a quick dump of the useful links that enabled me to figure this out:

These are the original two links that I saved from my first search. I studied them until beads of blood popped out on my forehead:
http://stackoverflow.com/questions/7113937/how-do-you-create-a-labelframe-with-a-scrollbar-in-tkinter
http://stackoverflow.com/questions/16188420/python-tkinter-scrollbar-for-frame

Here are some new very good links from my second Google search:
http://stackoverflow.com/questions/26979190/tkinter-simple-scrollable-text
http://knowpapa.com/scroll-text/
http://stackoverflow.com/questions/111155/how-do-i-handle-the-window-close-event-in-tkinter

Wednesday, March 9, 2016

Tkinter make a widget invisible or visible

The "disable" function greys out a check button and even a label, but is it possible to temporarily make those disappear off a screeen and reappear? So far what I've found seems to indicate that there are a couple of options. There seem to be some utilities for undoing packing in such a way that it's possible to easily redo it. It might also be possible to play with front and back layering to cover and uncover items on a GUI. Here are some links:

This is a nice discussion of these two methods: http://stackoverflow.com/questions/3819354/in-tkinter-is-there-any-way-to-make-a-widget-not-visible

A terse version of the same answer (it points to the first link as already answered): http://stackoverflow.com/questions/10267465/showing-and-hiding-widgets

Only slightly related, here's a cautionary tale about a guy who made a mess of his frame managers and how it was fixed: http://stackoverflow.com/questions/30061100/tkinter-self-grid-making-widgets-invisible

Monday, February 22, 2016

Tkinter check boxes

Tkinter doesn't have widgets that look like switches like Labview or anything, but apparently most OS's can be counted on to have check boxes so that's a thing in Tkinter. Either I'm finally getting used to this or it's' pretty easy to find useful examples on how to define checkboxs and how to grey them out:

Basic man page. In the examples the author seems to like the grid manager, but pack works just fine: http://www.python-course.eu/tkinter_checkboxes.php

A reminder to use an IntVar to return the status of the checkbox: http://stackoverflow.com/questions/16285056/get-the-input-from-a-checkbox-in-python-tkinter

A compact man page with nice lists of parameters and methods, including disable. http://www.tutorialspoint.com/python/tk_checkbutton.htm

A similar page for buttons showing how you can use the same settings to grey them out too: http://www.tutorialspoint.com/python/tk_button.htm



Monday, February 8, 2016

Globals in python

If your code is so bad that you're using globals, here's what you need to know:

Modules can read the global all they want, but the moment you set a value to it without first declaring in the module that it is a global, you're creating a local variable and not setting the global. Use the statement "global varname" in the code somewhere before the set. Modules which do not set it don't need this declaration. A reference:

Saturday, January 23, 2016

Triangular Number Series

It turns out that the minimum number of point to point resistance measurements that you have to make to test between all of the pins on any connector is given by something called the triangular number series. If you have only 2 pins to test, you just need to make one measurement. If you have three pins, you test from the first to the second, the first to the third, and the second to the third for three measurements. For four pins it's 6 measurements, for 5 it's 10 and so on. Each number of the series, 1, 3, 6, 10... is the previous number of the series plus the number of the next place!

Here is an online calculator for numbers in this series, although it's mostly of passing interest since it's really easy to code a triangular number calculator in any language:
http://www.mathgoodies.com/calculators/triangular-numbers.html

python tkinter label scrollbar 1

For my project I wanted to have an event log window showing to which I could write messages at the bottom and have them scroll up as more messages were added, with the top ones scrolling off the top of the window. I wanted to have a scrollbar on the side that would allow the user to access the earlier messages. In my searching, I found a few hints on how to implement a scrollbar, but initially couldn't make it work, so the first design that I got working was to instead have a fixed size Label widget to which new lines got added at the bottom, with the old lines simply scrolling out of view at the top.

There is some reason why a "Text" widget won't work for this application, I can't remember exactly why but I think that it might be an inability to dynamically update it. The "Label" widget allows you to use a StringVar to define its contents, and then update the StringVar any time you want to refresh the Label. As with most things in Python, there is no limit to the size of the StringVar, so I can be lazy and just keep adding and adding lines to the StringVar without having to worry about trimming text from the beginning; the fixed size of the label and anchoring the text to the bottom of the label then takes care of the scrolling for me.

Below is my actual design, in which I simply defined a fixed geometry for my Label widget, set wordwrap so that long horizontal lines get wrapped, then I defined the anchor for the text to be in the bottom left corner. Then I add lines to StringVar for the Label with '\n' after each new line I add. The Label redraws itself to show the new value of the StringVar, and any lines that don't fit within the fixed geometry are drawn but are off the top of the visible area so it gives the illusion of lines scrolling off the top. If the geometry of the widget weren't fixed, it would resize to show all of the lines. In this example code f is the main frame of my GUI; I pack the label widget into a new frame f5 which is in turn packed under some other objects that I'd defined earlier in the frame up to that point:

f5 = Tkinter.Frame(f)
self.stattext = Tkinter.StringVar()
self.stattext.set("")
self.status = Tkinter.Label(f5,textvar=self.stattext, justify="left",anchor="sw",width=80,height=10, wraplength=640)
self.status.pack(side="left", padx=10)
f5.pack(fill="x")

Here are some links with examples that look like what I did:
This is one where somebody is updating a StringVar to make a Label widget update. It doesn't have the fixed geometry like I used. The OP for this forum post has a minor problem urelated to the use of the Label. http://stackoverflow.com/questions/1918005/making-python-tkinter-label-widget-update

With regards to having a Label widget with a scrollbar, it turns out that scrollbars are not a native property of Labels, but since Labels by default resize themselves the answer is to put one in a "Canvas" which is a type of frame that you can define all kinds of parameters for such as that it doesn't resize but it can have scrollbars. Initially I was not able to get this to work, so I went with the other solution above. Here are some links about using a Canvas:

http://stackoverflow.com/questions/7113937/how-do-you-create-a-labelframe-with-a-scrollbar-in-tkinter

http://stackoverflow.com/questions/16188420/python-tkinter-scrollbar-for-frame

Friday, January 22, 2016

python tkinter how to pop up a window from inside a class

It took a little bit of searching and pondering of the info that I had found to accomplish one of the most important functions in my GUI after I recoded it to properly use the Tkinter mainloop, which is how to pop up custom dialog windows when something happened on the main GUI. My GUI is all under a single class, which is a good way of doing it but not much like the super simple examples that are often found online for creating dialog windows. I needed dialogs that were more customized than the built in Message or OK dialogs. The answer was for each dialog launched from the main GUI to create an instance of the Tkinter.Toplevel object and have that be the root of the new dialog window. This essentially creates a new window frame, it's like the Tkinter.Tk object that you use to create your GUI at the initialization of the class. You then pack data entry and/or display widgets into that Toplevel object. All of the objects you put in this frame are still accessible from the main class as long as you store the pointers to them in the class; essentially this new window is just an extension of the original window. Declare the callbacks for each of the widgets in the dialog as part of the class; you can allow the callbacks to destroy the Toplevel object by its pointer in order to perform the function of dismissing the dialog. There's a magic function of the Toplevel object (.transient()) which allows you to define that it appears on top of the original GUI window, and then you can place it using geometry commands like you would your main window. The only trick is to keep all the coding event-driven; for a complex program that means employing the state machine type of coding where you build the dialog in one state and then let user interaction with the dialog widgets cause advancement to a new state.

Here's my example of how I did it; not necessarily the best way but fairly functional:

import Tkinter,tkMessageBox,ttk
class mygui(Tkinter.Tk):

def __init__(self, *args, **kwargs):
Tkinter.Tk.__init__(self, *args, **kwargs)

self.title('My GUI Main Window')

# Making a fancy frame here with a blue border just for fun
# Bottom layer is a frame with blue fill
frm_0 = Tkinter.Frame(self, bg="blue")

# This is the main frame that will be on top of the blue frame
f = Tkinter.Frame(frm_0)

# Putting some text in the frame just to have a frame.
# Actual GUI would have more stuff
self.mylabel = Tkinter.Label(f,text="This is a label ",justify="left")
self.mylabel.pack(side="left",padx=10,pady=10)

# Place the main frame inside the blue frame with some padding
# so that the blue of the lower layer shows all around it
f.pack(fill="both",padx=5,pady=5)
frm_0.pack()

# Place the bottom frame where I want it (in the center)
frm_0.place(relx=0.5,rely=0.5,anchor="center")

# Make this example gui the size of the packed controls,
# in the middle of the screen
self.update_idletasks()
width = frm_0.winfo_width()
height = frm_0.winfo_height()
x = self.winfo_screenwidth() // 2 - width // 2
y = self.winfo_screenheight() // 2 - height // 2
self.geometry('{}x{}+{}+{}'.format(width, height, x, y))

# Initialize the state machine to the first state
self.state = 0

# Initialize other variables in this class
self.mytext = ''
self.text_accepted = False
self.abort_selected = False

# Define all the widget callback functions for the class
def accept(self, event=None):
self.mytext = self.e.get()
self.text_accepted = True
self.top.destroy()

def close_top(self):
self.mytext = ''
self.abort_selected = True
self.top.destroy()

# Main executive loop. This is where the part of the program that
# actually does things would go
def executive(self):

if (self.state == 0):
# First state, for doing stuff before popping up the dialog
print "Doing stuff in first state."

# Set next state, schedule the next call of exeutive() and exit
# In this example there is only one state before dialog; could
# be any number of states before the dialog
self.state = 1
self.executive()

elif (self.state == 1):
# Draw dialog popup
self.top = Tkinter.Toplevel()
msg = 'Enter text and press accept'
self.top.title(msg)

frm1 = Tkinter.Frame(self.top)
self.e = ttk.Entry(frm1)
self.e.config(width=(len(msg)+20))
self.e.insert(0,"default text")
self.e.pack(side="left",padx=5,pady=5)
b = Tkinter.Button(frm1, text="Accept", command=self.accept)
b.pack(side='left',padx=5,pady=5)
frm1.pack()

self.top.protocol("WM_DELETE_WINDOW", self.close_top)

# Make sure this dialog stays on top of the root console
self.top.transient(self)

# Make this dialog positioned in the center of the screen
self.update_idletasks()
win_width = self.top.winfo_width()
win_height = self.top.winfo_height()
x = self.winfo_screenwidth() // 2 - win_width // 2
y = self.winfo_screenheight() // 2 - win_height // 2
self.top.geometry('{}x{}+{}+{}'.format(win_width, win_height, x, y))

# set state to next state and exit
self.state = 2
self.executive()

elif (self.state == 2):
# waiting for the accept button to be pushed.
if self.text_accepted:
self.state = 3
self.executive()
elif self.abort_selected:
self.state = 4
self.executive()
else:
self.after(100,self.executive)

elif (self.state == 3):
# Do something with the input (boring example).
print self.mytext
self.state = 4
self.executive()

elif (self.state == 4):
# Exit state. Call the built-in .quit() function to exit the GUI
# Note that you can still call a built-in MessageBox widget any time
tkMessageBox.showinfo(title="Example complete",message="Example complete. Click OK to

exit.")
self.quit()

# Note that this "start" function is basically redundant, however having
# a function with this name helps readability.
def start(self):
self.state = 0;
self.executive()

if __name__=='__main__':

# Main code for example

app = mygui()
app.start()
app.mainloop()
app.destroy()

BeagleBone Debian Install Tkinter

This is the procedure that I've used twice now to update a fresh Debian distribution with Tkinter. The distro comes with Python 2.7 but not Tkinter.

Step 1: Put the BeagleBone on my home network with the CAT5 cable from the router. It gets a DHCP address on the network automatically from the router.

Step 2: Go to root user.
sudo su

Step 3: Update apt-get, which synchronizes what packages my distro has and doesn't have and establishes locations to download from.
apt-get update

Step 4: Download and install Tkinter. Despite what I read online about other users' issues with this step, it seemed to work fine for me.
apt-get install python-tk

Some related links:

The basic instructions, which include the above steps http://tkinter.unpythonic.net/wiki/How_to_install_Tkinter

About how to use apt-cache search which while not specifically needed to do this installation is generally helpful. Also, aptitude is mentioned: http://askubuntu.com/questions/160897/how-do-i-search-for-available-packages-from-the-command-line

More about apt-cache search, and also some more about how to use aptitude: http://www.cyberciti.biz/faq/searching-for-packages-in-debian-ubuntu-aptitude/





Wednesday, January 13, 2016

Python printing percent signs

Since percent is used as a formatting character, obviously it needs to be escaped somehow in formatted print statements to appear as itself. It turns out that the way to do this is to use two percent signs to print one, rather than using the backslash for escaping. The following slightly snarky forum answer describes this:

https://bytes.com/topic/python/answers/540689-printing-percent-sign

Python Tkinter progress bar

Progress bars are super easy in Tkinter, and there are two flavors. The regular kind is a bar that expands from left to right based on setting the object's "value" with respect to its "maxvalue". That is called a "determinate" progress bar. There is also an "indeterminate" progress bar that has a section that bounces back and forth from end to end to show general aliveness of a task. With an indeterminate progress bar, you can just call it's start() and stop() functions, or use a more direct method of showing aliveness by inserting step() commands in the code (.step accepts a percent value from 0 to 100). Some links:

http://stackoverflow.com/questions/7310511/how-to-create-downloading-progress-bar-in-ttk

https://gist.github.com/livibetter/6850443

The default Windows progress bar was pretty nasty looking, especially the indeterminate one which had a very thin indicator. It turns out that the way to change this is to define a ttk progressbar "style," which allows the programmer to chose from a handful of named styles, and then set colors for components. There's a command that you can do in a python console to get a list of available styles on whatever OS you're working in. Some are available on most platforms, others might be specific to whatever platform you're on. Some commentators to some forum threads that I checked out seemed to love the "clam" style, I preferred "classic" because it was big and blocky and with that name I was sure to find it on both Windows and Linux platforms. Some links about styles:

This shows how to use the theme_names() function of a Style object to get a list of additional styles. I can't see how you'd want to use this more than once, unless you were writing some really fancy code. http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-theme-layer.html

Here is the examples showing how to change the progressbar color, and the first example of using Style that I found. For some reason this guy thinks that "clam" is good looking style: http://stackoverflow.com/questions/13510882/how-to-change-ttk-progressbar-color-in-python

The man page for Style: https://docs.python.org/3/library/tkinter.ttk.html#tkinter.ttk.Style

Some solutions to trying to change the appearance of the progress bar. I solved my problem by just picking a different theme. This post proposes a torturous use of a canvas, while the second says to use a Style that allows for size adjustment. http://stackoverflow.com/questions/17912624/ttk-progressbar-how-to-change-thickness-of-a-horizontal-bar

Here's a man page for Progressbar that mentions that they have a Style option: https://www.tcl.tk/man/tcl/TkCmd/ttk_progressbar.htm

Here's a link that mentions somebody having a problem with their progressbar. The issue however was that the programmer wasn't properly making his code event-driven. http://stackoverflow.com/questions/16400533/why-ttk-progressbar-appears-after-process-in-tkinter

A nice man page for Progressbar that helped show the three methods that indeterminate progressbars have, start(), stop(), and step(). In the end, I found it helpful to just use the step() function for my indeterminate progressbar from my code rather than let it run on its own with start() and stop()
http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-Progressbar.html



My init code for drawing the progress bars on my gui:

import Tkinter, ttk

class MyGui(self, *args, **kwargs):
def __init__(self, *args, **kwargs):
Tkinter.Tk.__init__(self, *args, **kwargs)

self.title('My GUI')

s = ttk.Style()
s.theme_use('classic')
s.configure("blue.Horizontal.TProgressbar", foreground='blue', background='blue')

f = Tkinter.Frame(self)

self.aliveness = ttk.Progressbar(f, style="blue.Horizontal.Tprogressbar", orient="horizontal", length=600, mode="indeterminate")
self.aliveness.pack(padx=10,pady=10)

self.progress = ttk.Progressbar(f, style="blue.Horizontal.Tprogressbar", orient="horizontal", length=600, mode="determinate")
self.progress["value"] = 0
self.progress["maximum"] = 100 ## Note, not strictly necessary. If not specified 100 is assumed
self.progress.pack(padx=10,pady=10)

f.pack()

Tuesday, January 12, 2016

Python measuring and printing elapsed time

In order to benchmark the return times of some hardware interface code, I needed to print elapsed times from different parts of the code. Super easy to do in python, just use variable_x = datetime.datetime.now() to get datetime variables at different places in the code, and you can just directly subtract them from each other to get variables of type datetime.timedelta which have a seconds and microseconds part.

variable_1 = datetime.datetime.now()
.
.
variable_2 = datetime.datetime.now()
delta = variable_2 - variable_1
print "elapsed time is %d seconds %d microseconds" % (delta.seconds, delta.microseconds)
print "or %.6f seconds" %((delta.seconds * 1000000 + delta.microseconds)/1000000.0)

Reference links:

http://stackoverflow.com/questions/766335/python-speed-testing-time-difference-milliseconds

Sunday, January 10, 2016

Python continuation character

A recent google search for a python line continuation character didn't turn up any hits, which is odd because I am sure there is one. However, I found this interesting style guide for how to continue lines without continuation characters. It's tricky because of python's already existing specific use of indentation.

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

Wednesday, January 6, 2016

Python quit() function

For Python 2.7, there is no quit() function. However, here is an interesting discussion of what there is that does the same thing:

http://stackoverflow.com/questions/2823472/is-there-a-method-that-tells-my-program-to-quit

In retrospect, once I got better structure to my code, I didn't need this.

Python Tkinter File Dialog references

The built-in tkFileDialog classes are delightfully easy to use. Note, however, that they are not in the Tkinter library, you have to import the tkFileDialog library separately, which gets you the four different types of dialog objects. Some references:

http://effbot.org/tkinterbook/tkinter-file-dialogs.htm

http://tkinter.unpythonic.net/wiki/tkFileDialog


Python Tkinter Frame border color

It turns out that in Tkinter, you can set the width of a frame's border, but you can't set it's color. Since ttk objects differ from Tkinter objects, this may not necessarily be true for ttk frames (but I haven't checked yet). The only apparent way of creating color Tkinter frames around things is to layer frames within frames. First pack a frame with the desired color as it's bg color. Then pack another frame in that one, set fill="both" with some padx and pady to set the edges of the second frame in from the edges of the first frame, allowing the color of the first frame to show around the edges of the second frame. Then pack stuff into the second frame. Some links:

https://bytes.com/topic/python/answers/38448-changing-color-default-frame-border

http://stackoverflow.com/questions/4241036/how-do-i-center-a-frame-within-a-frame-in-tkinter

For possible future reference:

http://stackoverflow.com/questions/4320725/how-to-set-border-color-of-certain-tkinter-widgets


Linux how to make an icon that launches a python program

This turns out to be ridiculously easy. In most Linux distros, you can just put a text file where you want the launcher (like on the desktop), give it a .desktop extension, and add in text lines that define the location of the program to run and even the icon for the launcher file to show. Some links:

https://www.raspberrypi.org/forums/viewtopic.php?f=32&t=71468

This one is particularly nice because it's the actual standard, plus it's well-written to boot.

http://standards.freedesktop.org/desktop-entry-spec/latest/index.html


http://ubuntuforums.org/showthread.php?t=2221617

https://www.raspberrypi.org/forums/viewtopic.php?f=27&t=9817


Tuesday, January 5, 2016

Tkinter Frames are not the same as ttk Frames!

While doing a basic google search for command syntax, I stumbled across some forum threads which revealed that basic Tkinter objects such as Frame and Label have ttk equivalents with sometimes very different sets of features!

http://stackoverflow.com/questions/16639125/how-do-i-change-the-background-of-a-frame-in-tkinter

http://python.6.x6.nabble.com/LabelFrame-question-why-do-options-change-when-importing-from-tkFileDialog-td4527355.html