Python: GUI's, Exe's, and things like that.

Everything todo with programming goes HERE.
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

Thanks for the variety of responses.

As it turns out, I'm running into the same problem with threads again, so I'll have to dig into that a little deeper. Of course, any insight you can provide will be greatly appreciated since I'm pretty slow understanding this stuff. I'm becoming more reliant other people's suggestions rather than my own ability to track down answers myself. I'm stuck with search engines for all my needs (only one bookstore within 20 miles of my place and it doesn't have anything good). And when using search engines, well, there is a limit on how many different ways you can search a topic before you just get the same results over and over, especially if you don't understand what you're looking for in the first place. If those first dozen pages don't have an answer, you're out of luck for the time being. It's very frustrating actually, and lead me to write this rant.

So, off I go again. hopefully will overcome this hurdle in a fair amount of time.
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

I modified some code I found, but it doesn't work as I imagined. I'm able to start my while-loop, but I after I stop I can't start it a second time. While running I can start several more threads doing the same thing, all of which terminate on stop never to be started again. The desired action is to start/stop the while loop repeatedly, and never have overlapping threads. I also can't tell if this is a problem with Tkinter. I have GTK installed, but I haven't made a GUI with it yet. That will be this weekend I guess.

If anyone has a suggestion for threading, let me know. I'm having a very hard time visualizing what is going on.

Code: Select all

import time
from threading import Thread
from Tkinter import *


root = Tk()
stop = False

def start_stuff():
    stop = False
    thread = Thread(target = do_stuff)
    thread.setDaemon(True)
    thread.start()

def stop_stuff():
    global stop
    stop = True

def do_stuff():
    while not stop:
        print "this is a thread"
        time.sleep(1000)

frame = Frame(root)
start_button = Button(frame, text="Start", command = start_stuff)
stop_button = Button(frame, text="Stop", command = stop_stuff)

frame.pack(ipady=20)
start_button.pack(side=LEFT)
stop_button.pack(side=LEFT)

root.mainloop()
User avatar
Lucifer
Project Developer
Posts: 8640
Joined: Sun Aug 15, 2004 3:32 pm
Location: Republic of Texas
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by Lucifer »

You didn't do "global stop" in every function.

Also, you need to put your while loop inside an if...else construct, where the else is just a sleep, otherwise your loop function will consume 100% CPU waiting to be started again.
Image

Be the devil's own, Lucifer's my name.
- Iron Maiden
User avatar
Lucifer
Project Developer
Posts: 8640
Joined: Sun Aug 15, 2004 3:32 pm
Location: Republic of Texas
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by Lucifer »

Well, I don't have a generic threading class. What I have uses threading.Thread, so google that. "python treading Thread". That'll give you a class you can inherit that works the way you expect it to. It really simplifies threads.

You also need to consider using semaphores to lock the variable that controls whether the thread is doing anything or not. That'll prevent a race condition. Generally speaking, if the thread itself never writes to that variable, you're fine to not use semaphores, but look through the docs anyway. Python has a class for that, too.
Image

Be the devil's own, Lucifer's my name.
- Iron Maiden
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

Lucifer wrote:You didn't do "global stop" in every function.
Damn dude, I owe you a beer. That brings about the desired effect.
Lucifer wrote:Also, you need to put your while loop inside an if...else construct, where the else is just a sleep, otherwise your loop function will consume 100% CPU waiting to be started again.
So, what would I set the IF condition to? I don't follow. Like this...?

Code: Select all

def task():
    if (state.get() == something):
        while not stop:
            print "I'm doing something here..."
            print "And now I'm going to repeat"
    else:
        time.sleep(1)

Lucifer wrote:Well, I don't have a generic threading class. What I have uses threading.Thread, so google that. "python treading Thread". That'll give you a class you can adjks teoer jfd df weorier sdfjsdokf ttrk aldlasd j tpas thkia sd ll. jasdajldi wnnt't jasd jsksd............
^^ That's literally how you last post looked in my brain. I'm sorry, I have a very hard time visualizing what a thread is and how it works, and I certainly have a hard time understanding all the other terms like locking, blocking, queuing, pooling, etc... I have yet to find an explanation dumbed down enough.

There is one thing I need to learn for sure. I would like to restrict the number of threads down to one. In order to prevent the user from starting multiple threads, I rewrote the start function to first "stop" then "wait" about a second for the previous thread to die. This is pretty sloppy for sure, but that's the limit of my knowledge.

Thanks for all the help so far.
User avatar
Lucifer
Project Developer
Posts: 8640
Joined: Sun Aug 15, 2004 3:32 pm
Location: Republic of Texas
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by Lucifer »

Your if condition looks like the right idea.

Ok, threads are surprisingly simple ideas but complicated to implement. The idea is basically the difference between singing two parts of a song by yourself, and having two people sing them at the same time. You know, like in a recording studio. Sure, you *can* overdub, but you can get the recording done twice as fast if you have two people to sing it at the same time.

And that's pretty much it, really. Your program can do two things at the same time, or more.

So, in this situation, you have a single thread in the process that runs the GUI. This thread has to poll for input, draw the GUI, figure out what happened when, and then execute code that does real work. When the real work a program does is processor intensive, or ongoing, you generally want to put that in a thread of its own. That way, it can *do* that work without having to stop working to poll for input, draw the GUI, etc.

I guess a better analogy is the bar. You have a bartender. When he works by himself, he has to mix and serve drinks, take money, and clean the tables and the bar. If he hires a barback, now he has someone to clean the tables and the bar, giving him more time to mix and serve drinks and take money. In that scenario, the barback is a new thread.

Ok, so, now you have these two threads that are accessing the same variables at the same time. It's the classic "first past the post" scenario. Consider you being on a picnic, and you want to eat a sandwich. If you're all by yourself, no problem, you grab the sandwich and eat it. If you've got a girl with you, and she wants the sandwich, and you both reach for it at the same time, one of you will get it and one of you will not. Manners dictate that you both stop and offer the sandwich to the other person.

That situation, in code, is referred to as a "race condition", because it's a race to get to the sandwich first. To avoid that, we use locking conventions where the two threads that want to access something have to wait until it is unlocked before they can access it. For long strings of data, you can easily see where this might be a problem. Consider your audio buffer. You copy data into it with one thread, and then another process entirely takes it and plays it through the speakers. If you don't copy the data fast enough, then the other process could either wind up playing silence, or it might repeat stuff previously played. Maybe that's not a good example, I'm pretty tired right now.

So you have a variable in your thread class that signals whether or not you're playing something. If your thread class tries to read it at the same moment your GUI thread is trying to change it, then there could be trouble. If they are both trying to write to it, there *will* be trouble.

Ok, I'm going to stop there for now, I'm about to jump off the deep edge into technobabble.
Image

Be the devil's own, Lucifer's my name.
- Iron Maiden
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

Ok, I think I'm starting to understand a little.

I rewrote some of my code there is almost no chance of the user creating multiple threads, and the previous thread seems to die in a dignified fashion. I did some research on while-loops and CPU usage. I then checked my own usage with the program was running and found no significant increase. I think this is because the program spends most of it's time sleeping. Sleeping is part of the while-loop.

I'll still try to nest it in a IF statement and attach a conditional, but I haven't any idea what that conditional should be right now. And I'm not going to worry about it until later because I'll spend the next few days on GUI design, something I'm pretty excited about. The hardest part of that, I think, is deciding on a traditional look or something wacky.
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

This project is just about to enter the final stage. That is, getting it to run on other machines, including Windows and Macintosh.

Before I get there, I want to ask about standards. (Later I'd like whoever is interested to critique my code. Standards aside, it looks pretty good right now -- except where I deliberately left out error handling, haha.)

I want to know about the top of a program, the commented heading, the area before imports. What is the best information to include? Anything else besides "program name/version, code version, author, date, and description?"

Also, I'm thinking about licenses and maybe putting this on sourceforge.net. I did a quick search last night and found exactly zero projects related to "wind chimes." Any helpful links you can drop here would be great. Thanks.
User avatar
Lucifer
Project Developer
Posts: 8640
Joined: Sun Aug 15, 2004 3:32 pm
Location: Republic of Texas
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by Lucifer »

The top of every source file should include a copyright notice and license information. If it's simply "All rights reserved", then you have to put that.

I would suggest you take a look at doxygen for other things to put in. :) I try to add a long comment section describing what's in the file.
Image

Be the devil's own, Lucifer's my name.
- Iron Maiden
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

Lucifer wrote:The top of every source file should include a copyright notice and license information. If it's simply "All rights reserved", then you have to put that.
Cool. I looked into "all rights reserved" and apparently it's not needed after the year 2000; something about all rights being assumed now. But I still haven't decided on a license. I've started a thread here with hopes of a discussion about the pros and cons of the GPL vs OSL. Not that it really matters much for the trite little script I wrote, but I'd like to share it eventually and this licensing stuff is something I'm curious about anyway.
Lucifer wrote:I would suggest you take a look at doxygen for other things to put in. :) I try to add a long comment section describing what's in the file.
Thanks. Although I didn't get heavy into doxygen, I did take some of their ideas. The comments I have can be adapted very, very easily to use with doxygen -- just a matter of adding an extra # and a @tag. Cool stuff. Maybe if I decide to write something larger and less silly I'll get serious about doxygen.


So, now I'm in the final stage of development. I have a fully functioning script with a simple GUI running in Linux. I've done my best to bug test it and I can't even get the thing to crash no matter how hard I try, so I think I'm good to go. The next step is to get it working on windows so I can make an .exe and share it with my friends. I've already hit the first obstacle. One of the third-party modules I use comes only as a tar.gz and I haven't the slightest idea how to get this installed in Windows. I'll keep looking for an answer, but as usual, if you have any suggestions they will be highly appreciated.
User avatar
Lucifer
Project Developer
Posts: 8640
Joined: Sun Aug 15, 2004 3:32 pm
Location: Republic of Texas
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by Lucifer »

Which module are you using that only comes as a tarball?
Image

Be the devil's own, Lucifer's my name.
- Iron Maiden
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

Lucifer wrote:Which module are you using that only comes as a tarball?
scikits.samplerate. The last version with an installer was 0.3.1 and they are on 0.3.3. No worries though, I managed to find an 'unofficial' installer and it worked. I have the program up-and-running on WinXP. Since it took me two whole days to get it working, I haven't tried building an EXE yet (two days seems really lucky to me, btw). PyInstaller looks like the better choice over py2exe since you can tweak how APIs get included, thus reducing file size. BUT... I don't really understand it and there are more py2exe tutorials out there. And, well, you know, "path of least resistance."

I'm thinking this forum might be a good place to have people test the .exe when I get it. Lots of Windows users. I only have XP. And I guess I'm looking for someone with a Mac who wants to help out too... haha.
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

Well, I managed to build an .exe on my WinXP box using PyInstaller. I gave a copy of the program to my friend running Win7. Nothing worked. He tried it from the command line and in compatibility mode too. Nothing. So, I guess this project is dead. There is nothing more I can do. I gave it my best shot. Thanks for all the help you guys gave me. Maybe I can find a solution one day when I get interested again.
User avatar
sinewav
Graphic Artist
Posts: 6413
Joined: Wed Jan 23, 2008 3:37 am
Contact:

Re: Python: GUI's, Exe's, and things like that.

Post by sinewav »

I made a video showing the program working on Linux, where it will stay until I get smart enough to get it working on another platform (unlikely), or rewrite it in another language (likely).

Wind Chimes
chrisd
Round Winner
Posts: 315
Joined: Sat May 29, 2010 1:13 pm

Re: Python: GUI's, Exe's, and things like that.

Post by chrisd »

Well, Sine, no need to despair yet.... This PyInstaller thing might get updated. Maybe you could file a bugreport describing what you did or people there could help you. Does that project have a mailing list?
Post Reply