Python: GUI's, Exe's, and things like that.
Python: GUI's, Exe's, and things like that.
I got a naked program and it needs a cool suit. I've never drawn a GUI. Before I start that process, I wanted to get some advice. The ultimate goal would be to package my program up so others can use it on Win/Mac. This, I think, will not be achieved. I will probably abandon the project when the level of frustration gets too high.
The program is in Python with the pygame module and a few sound-related modules. It seems the easiest and most direct thing to do is to use the capabilities of pygame to interface with the user (it also seems the most fun and interesting). I know of a utility named cx_freeze, but I've yet to find anything dumbed down enough for me to understand.
If you have and similar or related experience with Python, GUI's, and crossing-platforms, I would love to hear from you.*
* I understand I probably should just learn C++ and get on with it instead of messing around with this other junk. But, I'm not too smart, and tend to follow the path of least resistance even though it might make my journey ridiculously long.
The program is in Python with the pygame module and a few sound-related modules. It seems the easiest and most direct thing to do is to use the capabilities of pygame to interface with the user (it also seems the most fun and interesting). I know of a utility named cx_freeze, but I've yet to find anything dumbed down enough for me to understand.
If you have and similar or related experience with Python, GUI's, and crossing-platforms, I would love to hear from you.*
* I understand I probably should just learn C++ and get on with it instead of messing around with this other junk. But, I'm not too smart, and tend to follow the path of least resistance even though it might make my journey ridiculously long.
Last edited by sinewav on Sat Dec 31, 2011 9:13 pm, edited 1 time in total.
Re: Python: GUI's, Exs's, and thing like that.
Hello Sine!
I am not sure why you would think that this project is not going to succeed. It is not really that complicated to create a GUI (if you do not need too many features). Also, I am not going to say that you should learn C++. C++ is nice if you are a professional programmer or want to write something impressive like Armagetron, but really, I would recommend Python if you only occasionally write something relatively simple. Not that I have ever done that much in Python.... Since I am very fluent in C++ I tend to use it for more or less everything.
Good luck!
Chris
I am not sure why you would think that this project is not going to succeed. It is not really that complicated to create a GUI (if you do not need too many features). Also, I am not going to say that you should learn C++. C++ is nice if you are a professional programmer or want to write something impressive like Armagetron, but really, I would recommend Python if you only occasionally write something relatively simple. Not that I have ever done that much in Python.... Since I am very fluent in C++ I tend to use it for more or less everything.
Good luck!
Chris
Re: Python: GUI's, Exe's, and things like that.
Well thanks chrisd. I'm really in the dark here though. I only have one friend who is a programmer, but all the code he's written over the last dozen years has been for satellites and modems, and he's never written a GUI.
So maybe I can ask you this: If I complete my program in Linux, do I need to get the whole thing running on a dev-environment in Windows and create an executable from there? Is it possible to make an .exe in Linux and expect it to run on Windows? And what about Macintosh?
So maybe I can ask you this: If I complete my program in Linux, do I need to get the whole thing running on a dev-environment in Windows and create an executable from there? Is it possible to make an .exe in Linux and expect it to run on Windows? And what about Macintosh?
Re: Python: GUI's, Exe's, and things like that.
Well, it depends. Are you going to be the only user or are others expected to install this software as well? If those others are reasonably computer savvy they could install python and the GUI library that you decide to use and then they get an archive file with all the python code (or compiled python code) from you and they can just run it. On some platforms python will already be there. With a bit of luck it is just installing a few packages a few clicks and they are done. This is not too difficult and it is totally cross platform, provided that your application is not too particular of the exact version of python. If you want to make it easier, there are tools to create native executables for various platforms. But in that case you will have to do more work. If you google for things like "python distribute executable" you will find lots of information. E.g., http://hackerboss.com/how-to-distribute ... lications/
You also need to check the documentation of the GUI library that you are going to use.
You also need to check the documentation of the GUI library that you are going to use.
Re: Python: GUI's, Exe's, and things like that.
Hmm, I guess it should have an installer. The program is extremely simple and I want people to be able to run it with a double-click, and without installing any other software. Here, let me tell you about what I have so far...chrisd wrote:Are you going to be the only user or are others expected to install this software as well?
It's a simulation of wind chimes. There are 4 "materials" to choose from (different size metal and one for bamboo). There are also 4 "scales" and "modes" to play them in. The scales are numbers and arrangements of notes, and modes are unlike modes in music theory, rather they deal with the base pitch and the amount of dischord. Finally, there are two settings for the "intensity" of the wind (chime clustering) and the "frequency" (how often they ring); and a master volume.
So, going with my modus operandi of following the path of least resistance, I found some tutorials on Tkinter (python-tk). It's cross-platform and I'm hoping I won't have problems with building this for other OS's. Right now I'm stuck on threading, which I guess I need to make this program run properly. It's tough going because I'm not too bright with this stuff. I still have no understanding of OOP at all, so I pass on all tutorials framed that way.

I'll post back when I get closer to having a completed project on my machine. And I still have to name it.
Re: Python: GUI's, Exe's, and things like that.
I would say, try to stay away from threads if you possibly can. Threads can easily get very complicated and quite prone to ununderstandable behavior and for not-so-very-complicated programs you can almost always avoid them. OOP on the other hand is very useful to know and it is sort-of unavoidable. Each and every GUI library in this world is based on object oriented ideas. Although you may be able to mostly avoid OOP in your own code it is there anyway in the GUI library.sinewav wrote:So, going with my modus operandi of following the path of least resistance, I found some tutorials on Tkinter (python-tk). It's cross-platform and I'm hoping I won't have problems with building this for other OS's. Right now I'm stuck on threading, which I guess I need to make this program run properly. It's tough going because I'm not too bright with this stuff. I still have no understanding of OOP at all, so I pass on all tutorials framed that way.
Re: Python: GUI's, Exe's, and things like that.
That would be great, but there is a while loop I can't break out of once I start the chimes. It freezes the GUI too. I guess I'm at the current crux of my understanding. I have some functions that work really great. I have a working GUI. I can't get them together.chrisd wrote:sinewav wrote:I would say, try to stay away from threads if you possibly can. Threads can easily get very complicated and quite prone to ununderstandable behavior and for not-so-very-complicated programs you can almost always avoid them.
I will say this for sure: I'm completely amazed I even got this far. You're talking to a guy who can't really do algebra. I barely placed in high school math the last time I took an entrance exam.
Re: Python: GUI's, Exe's, and things like that.
For your purposes, the Tkinter library that ships with Python is the best gui for you to use. It provides you all of your goals, plain and simple.
cx_freeze is nice, iirc. Use py2exe in windows. You should be able to get Wine to run all of the relevant stuff when you get that far.
For threading, remind me when I get back from Texas in a couple of days and I'll give you a class that encapsulates a thread for you to use. I've written several in Python.
cx_freeze is nice, iirc. Use py2exe in windows. You should be able to get Wine to run all of the relevant stuff when you get that far.
For threading, remind me when I get back from Texas in a couple of days and I'll give you a class that encapsulates a thread for you to use. I've written several in Python.

Check out my YouTube channel: https://youtube.com/@davefancella?si=H--oCK3k_dQ1laDN
Be the devil's own, Lucifer's my name.
- Iron Maiden
Be the devil's own, Lucifer's my name.
- Iron Maiden
Re: Python: GUI's, Exe's, and things like that.
Excellent, I'll remind you. Hopefully I'll understand it. I can't quite grasp Classes yet.Lucifer wrote:For threading, remind me when I get back from Texas in a couple of days and I'll give you a class that encapsulates a thread for you to use. I've written several in Python.
Re: Python: GUI's, Exe's, and things like that.
There are two ways out of this. There is a solution with two threads or a solution with just one thread.sinewav wrote:That would be great, but there is a while loop I can't break out of once I start the chimes. It freezes the GUI too. I guess I'm at the current crux of my understanding. I have some functions that work really great. I have a working GUI. I can't get them together.
With two threads: The while loop runs in one thread, so it does not block the GUI anymore. While running, it reads some global data that influences its behavior. This global data is modified by the GUI. At the same time this is where the problem with threads is: if you are not careful you might be writing and reading at the same time and the data might be in an in-between state that is garbage. There are solutions to this, such as locking the data or makings sure that the data remains valid at all times by being careful, for instance by using atomic operations.
With just one thread: Your while loop is no longer a while loop, just a function, let us call it ProduceSound to give the animal a name. Every GUI has a message loop that makes it respond to events. E.g., if a button is clicked a message is posted and when the program again looks at the message queue, it executes one message (for instance this click), and looks again at the queue. At the end of your ProduceSound, you post a call to the ProduceSound function back into the message queue. This has the effect that ProduceSound is called over and over again, which recovers the behavior of the while loop. However, if buttons are clicked those are also posted in the same queue, so they are handled as well in between the calls to ProduceSound. The important thing here is that you have to make sure that all clicks and other GUI events are handled fast enough, so that the delay in subsequent calls to ProduceSound is not noticeable in the audio.
Re: Python: GUI's, Exe's, and things like that.
Well, classes are also the core concept of object oriented programming. Okay, I will try to give you a 5 minute course on them. I will be using notation more or less like in C++ because I think the Python notation is leaving out too much making thing a bit unclear.sinewav wrote:I can't quite grasp Classes yet.
Well, you have types, right? For instance, a variable can hold something of type integer. One writes
int x = 5;
Now the variable x of type int and it holds the value 5. A class is basically a different kind of type. One that the user can define himself. So, if the user creates a class A by writing something like
class A
{
....
}
He can then create variables of type A. As in
A x = 5;
The "= 5" is there to make it look almost the same as the "int x = 5" example. It may or may not be possible to initialize an object of class A this way, depending on the exact definition of A. It might also be that just writing "A x" is enough to create a variable of type A.
We can put data members and functions in a class. E.g., A could look like
class A
{
int x = 5;
AddTen() { x = x + 10; }
}
Here the class A holds a data member x that is initialized to 5. There is a member function that increases the current value of x by 10.
One could do the following with this class
A a, b; // a and b are variables of type A.
a.AddTen();
Print (a.x) // this prints 15 because we just called AddTen.
Print (b.x) // this still prints 5 because we never called the AddTen of b.
Remarkably enough, one of the big things of of a class is actually what it makes impossible to do. In C++ and Java, it is possible the make parts of the class generally accessible and parts of it only accessible from member functions of the class. Doing that to the class A gives me
Code: Select all
class A
{
public:
AddTen() { x = x + 10; }
int GetValue() { return x; }
private:
int x = 5;
}
One might also imagine that a.x is a value that needs to be stored between runs of the program. Therefore, it is written into a file. With a class one can make sure this happens by writing it to the file again whenever the value is changed by a method in the class, just by letting this method do it. If it is a public member any line of code anywhere could be changing the value a.x and it could easily be forgotten somewhere to write it to the file.
Also the components of a GUI are classes. GUI libraries have classes "Button", "HorizontalSlider", "Window" and so on. If one wants a horizontal slider and a button in a window one might need to do something like.
Window w;
HorizontalSlider s;
Button b;
w.Add(s);
w.Add(b);
The funny thing is that the add() member function of Window can take more then one type, but not just any type. It does not make sense to add something that cannot be drawn into a window, because a window consists of things that are to be drawn on top of each other in a visible window on the screen. In a GUI library these classes might, (leaving out a lot, obviously) look like
Code: Select all
class Widget // a Widget is something that can be drawn on the screen.
{
Draw() { ...}
}
class Button: Widget
{
Draw() { ... }
}
class HorizontalSlider: Widget
{
Draw() { ... }
}
class Window
{
public:
Add (Widget w) { .... code that adds w to l .... }
ShowTheWindow()
{
for (all the widgets w in l)
w.Draw();
}
private:
WidgetList l; // A list of all the widgets that have been added to the Window
// using the Add() method.
}
Okay, that is my "OOP in 5 minutes" course.
Re: Python: GUI's, Exe's, and things like that.
Excellent, thanks. The greater variety of explanations that are available to me, the greater my chance for understanding. Although, my mind contemplating computing is like a sleepy eye with things going in and out of focus. Sometimes is say "ah-ha!" then immediately forget my revelation.chrisd wrote:Okay, that is my "OOP in 5 minutes" course.
Once I looked into threading, I discovered that Tkinter (the widget pack) is a little sketchy with threads. I tried a single thread version and the results were irregular. I managed to find a double-thread code snippet calling two classes into a queue (the GUI and another containing the while-loop), but I don't have a complete grasp on it yet. I did, however, take the time to look into classes again in an effort to stretch my brain around them.
I managed to create a working class from out my programs functions. There was some trial and error, mostly because I get hung up on reference variables (unlocking this might be the key to my understanding of classes). Either way, it works even though I only have a vague notion of how, haha.
And I've decided to forget about the Tkinter widget pack for now. I'm now going back to my original idea of using the pygame api to interface with, since I'm already using it in the program. Less imported apis == less trouble later, right? And, I'va already demonstrated to myself that I can start and stop a while-loop in pygame. Path of least resistance again!
But, I have plans to return to Tkinter GUI making immediately after I finish this program (or sooner if I just need a break). Earlier in the year I wrote a music utility in Java and never put a face on it. I think it's a perfect program to convert to Python and make pretty. I think programming in Python is really helping drive home the basics and I feel that once I have a better understanding of the overall process, I'll be able to do more in Java (which seems a bit cumbersome to use from my perspective).
Re: Python: GUI's, Exe's, and things like that.
The problem with this approach is that you can have dropouts in the sound caused by excessive GUI interaction. Which you pointed out, but I wanted to point it out too.chrisd wrote: With just one thread: Your while loop is no longer a while loop, just a function, let us call it ProduceSound to give the animal a name. Every GUI has a message loop that makes it respond to events. E.g., if a button is clicked a message is posted and when the program again looks at the message queue, it executes one message (for instance this click), and looks again at the queue. At the end of your ProduceSound, you post a call to the ProduceSound function back into the message queue. This has the effect that ProduceSound is called over and over again, which recovers the behavior of the while loop. However, if buttons are clicked those are also posted in the same queue, so they are handled as well in between the calls to ProduceSound. The important thing here is that you have to make sure that all clicks and other GUI events are handled fast enough, so that the delay in subsequent calls to ProduceSound is not noticeable in the audio.
Check out my YouTube channel: https://youtube.com/@davefancella?si=H--oCK3k_dQ1laDN
Be the devil's own, Lucifer's my name.
- Iron Maiden
Be the devil's own, Lucifer's my name.
- Iron Maiden
Re: Python: GUI's, Exe's, and things like that.
Look at it this way. If you have a variable, this stands for a particular location in the memory in the computer. What is at this location? It depends. The object that the variable refers to might be there. But there can also be another memory address there and the actual object is at this latter memory location. Does this matter? Well, quite a lot. If we dosinewav wrote:I managed to create a working class from out my programs functions. There was some trial and error, mostly because I get hung up on reference variables (unlocking this might be the key to my understanding of classes). Either way, it works even though I only have a vague notion of how, haha.
A a = A();
A b = a;
If at the addresses that belong to a and b there are actual objects of type A, then we have two objects of type A in memory after this code has run. If a and b are just references, i.e., at the memory location of a and b the memory address of the real object is to be found, then a and b contain the same address and there is in total just one object of type A in memory. If the size of an object A happens to be 300 MB it is rather important whether there is one or two of them.
Also, if I now do a.x = 3, in the former case only the object a has changed but in the latter case also b.x has changed, because a and b are actually the same object.
I am not entirely sure about Phyton, because I basically never use it, but I think in the above example the second possibility is actually the case. So all variables are actually references to objects and the objects themselves are somewhere else. This is also important when objects are passed to functions. If this is done by reference (which it probably is in Python) then changing a member variable inside a method actually also changes the object outside of the function. Some classes compensate for this by always creating a new object of that class whenever you call a method that is supposed to modify the value of the object.
I tend to agree. Java becomes easier to use with a good IDE (like Eclipse) but for quite simple tasks one tends to need quite a lot of classes and without an IDE it is rather endless typing. And setting up Eclipse to work as you want it is often, for me at least, quite a fight. The advantage is though that it may very well be a lot easier to create a cross-platform executable using Java than with Python.sinewav wrote:I'll be able to do more in Java (which seems a bit cumbersome to use from my perspective).
Re: Python: GUI's, Exe's, and things like that.
I think I might have a simpler explanation for references. 
Neal cooks up a meal, right? There are two possible ways to serve it:
1) Everybody gets their own plate. In this case, every diner has their own personal copy of the meal.
2) Everybody shares a single plate. In this case, every diner shares the same instance of the meal, and is given a reference to where they can find it (Neal says "Here's your damn dinner!").
Python doesn't do copying. You have to explicitly copy objects when you want to actually make a copy. Other languages are different. C++ automatically copies objects and variables in particular situations, while in others it only passes references.
It's worth considering how PHP does it. PHP allows passing objects by reference with a special syntax. When you do that, the interpreter has to manage all of the references. When there are no other things that reference an object, it is erased from memory. This is called garbage collecting, and Java and Python do it too. There's overhead involved, so you're only supposed to pass objects by reference if you need the receiving function to be able to modify the object for everybody. That would be when Mya decides to salt the fries Neal served on the community plate. Now they're salted for everybody.
If you had your own copy, yours would have been unaffected by the salting. Anyway, when you don't pass by reference in PHP, then you pass a copy. Now, in C++ the object would be copied, so the overhead in dealing with references and the garbage collector is actually more of a load than letting the object be copied. But in PHP, if you pass a copy, an actual copy isn't created until you change the object. At that time, a new object is created that is a copy of the old one, and then it is changed the way you asked it to. This is called Copy On Write. So if you pass an object to a function, and the function doesn't need to change the object's data at all, then you actually get a performance increase by passing copies rather than passing references. This situation, naturally, offends C++ programmers.
As I said, Python doesn't copy objects at all. There is a module you have to import if you want to copy objects, and there's a builtin function that doesn't do a very good copy. Everything is passed by reference in Python. Which means every function that uses an object can change the object's members and piss off all the other diners.

Neal cooks up a meal, right? There are two possible ways to serve it:
1) Everybody gets their own plate. In this case, every diner has their own personal copy of the meal.
2) Everybody shares a single plate. In this case, every diner shares the same instance of the meal, and is given a reference to where they can find it (Neal says "Here's your damn dinner!").
Python doesn't do copying. You have to explicitly copy objects when you want to actually make a copy. Other languages are different. C++ automatically copies objects and variables in particular situations, while in others it only passes references.
It's worth considering how PHP does it. PHP allows passing objects by reference with a special syntax. When you do that, the interpreter has to manage all of the references. When there are no other things that reference an object, it is erased from memory. This is called garbage collecting, and Java and Python do it too. There's overhead involved, so you're only supposed to pass objects by reference if you need the receiving function to be able to modify the object for everybody. That would be when Mya decides to salt the fries Neal served on the community plate. Now they're salted for everybody.

As I said, Python doesn't copy objects at all. There is a module you have to import if you want to copy objects, and there's a builtin function that doesn't do a very good copy. Everything is passed by reference in Python. Which means every function that uses an object can change the object's members and piss off all the other diners.
Check out my YouTube channel: https://youtube.com/@davefancella?si=H--oCK3k_dQ1laDN
Be the devil's own, Lucifer's my name.
- Iron Maiden
Be the devil's own, Lucifer's my name.
- Iron Maiden