Quantcast

Jump to content


Photo

Python GUI programming


  • Please log in to reply
27 replies to this topic

#1 Analog

Analog
  • 13 posts

Posted 24 June 2010 - 08:42 PM

Hi guys, I've recently taken up python programming and have familiarized myself with syntax and what seems to be useful for internet applications (get, post, cookies)..and am wondering if somebody can direct me to a guide or tutorial for how to start integrating my code into a GUI. I've researched wxPython, and installed it, but am unsure where to go. I come from a background of VB6, VB.NET and non-GUI command line C++ and have never had to program a GUI from scratch and personally integrate code.

I was wondering if somebody could direct me to a Visual-esque GUI generator, or to some good guides on entry-level GUI integration. I understand the concept of handlers and how to define buttons, but now how to put it all together.

Thanks for any assistance :)

#2 iargue

iargue
  • 10048 posts


Users Awards

Posted 24 June 2010 - 08:47 PM

Look into wxDesigner. Its what we use.

#3 Analog

Analog
  • 13 posts

Posted 24 June 2010 - 09:32 PM

Look into wxDesigner. Its what we use.


Link? It seems the main website is down or gone.

EDIT: I may have found it, but am unsure if it's what you're talking about. I'll play with it tomorrow, thanks for directing me, though. Is it difficult to program GUI's? I've kinda grown attached to the language, and would be sad if GUI scripting would deter me. D:

Edited by Analog, 24 June 2010 - 10:14 PM.


#4 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 24 June 2010 - 10:18 PM

I suggest PyGTK and GTK+. Use Glade as your GUI designer and export your GUI as XML. Then use PyGTK's API to connect your functions to GUI events and you'll be on your way. Couldn't be easier. We would have used PyGTK here but we wanted mac support. Turns out, wx has it's quirks on macs and we'll be researching whether we want to switch some time this summer.

#5 Analog

Analog
  • 13 posts

Posted 24 June 2010 - 10:22 PM

In text, that sounds really easy and awesome, but coming from a background of visual studio development, I've never linked anything to my GUI directly. I'm sure with all of these names of common GUI related terminology, I can surf around and find something, unless you know of a good source for a guide. Thanks for the replies guys :)

#6 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 24 June 2010 - 10:25 PM

Sorry, I should have posted links: http://www.pygtk.org/

Check out their tutorials page to get you started. They discuss a lot of stuff about adding controls directly through code. That's fine and all, but it becomes cumbersome after a while, so I suggest using a GUI designer: http://glade.gnome.org/

Let me know how it goes :).

#7 Analog

Analog
  • 13 posts

Posted 24 June 2010 - 10:32 PM

Sorry, I should have posted links: http://www.pygtk.org/

Check out their tutorials page to get you started. They discuss a lot of stuff about adding controls directly through code. That's fine and all, but it becomes cumbersome after a while, so I suggest using a GUI designer: http://glade.gnome.org/

Let me know how it goes :).


Those looks promising! When I actually get a chance to sit down tomorrow I will definitely go over those. Also, do you suggest linux or windows for development? I find it easier on windows, but more...smooth on linux. If you know what I mean.

I'll keep you updated. Thanks again. :)



#8 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 24 June 2010 - 10:38 PM


Those looks promising! When I actually get a chance to sit down tomorrow I will definitely go over those. Also, do you suggest linux or windows for development? I find it easier on windows, but more...smooth on linux. If you know what I mean.

I'll keep you updated. Thanks again. :)


Either is fine. Use whatever you're most comfortable in. I personally prefer Linux but that's because I like the terminal :p. Furthermore, Windows just doesn't have awesome tools like grep, awk, sed, etc. that make using *nix so fun. But that's just me. It's clear that many people get by just fine without those tools :p.

#9 Dan

Dan
  • Resident Know-It-All

  • 6382 posts


Users Awards

Posted 25 June 2010 - 05:49 AM

Either is fine. Use whatever you're most comfortable in. I personally prefer Linux but that's because I like the terminal :p. Furthermore, Windows just doesn't have awesome tools like grep, awk, sed, etc. that make using *nix so fun. But that's just me. It's clear that many people get by just fine without those tools :p.


grep keys /house/

#10 WhiteRabbit

WhiteRabbit
  • 86 posts

Posted 25 June 2010 - 05:04 PM

In all truth I would love to see the programs here on neocodex become cross platform to run natively linux... I've been slowly teaching myself python and have started to try and imitate some of the programs here in the terminal, but without much luck...

Edited by WhiteRabbit, 25 June 2010 - 05:05 PM.


#11 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 25 June 2010 - 07:38 PM

grep keys /house/

Since when has Windows had grep?


In all truth I would love to see the programs here on neocodex become cross platform to run natively linux... I've been slowly teaching myself python and have started to try and imitate some of the programs here in the terminal, but without much luck...

There's nothing stopping us from releasing our programs on Linux actually... our programs run wherever python runs, and that's a lot of places, Linux included :p. The reason we haven't made much effort towards that end is that the market for linux isn't as high as windows. We're trying for Mac since there are quite a few members who use Mac. We'll see about linux after that :p.

#12 Analog

Analog
  • 13 posts

Posted 26 June 2010 - 09:43 AM

After messing with glade for a good bit, I have no idea how to get it to do what I want it to do. I want to create the parent window, and add things to it, similar to Microsoft's visual designer. Is this possible? Or am I missing the ideology behind what this program does. Looking for some guidance :)

EDIT: Finally figured that out, but now just to connect everything. Any good ideas or samples of python code that connects the GUI/handlers to the actual code?

Just trying to get some output, from a tutorial I have this code:

import sys
try:
 	import pygtk
  	pygtk.require("2.0")
except:
  	pass
try:
	import gtk
  	import gtk.glade
except:
	sys.exit(1)

class HellowWorldGTK:
	"""This is an Hello World GTK application"""

	def __init__(self):
		
		#Set the Glade file
		self.gladefile = "Derp.glade"  
        	self.wTree = gtk.glade.XML(self.gladefile) 
		
		#Create our dictionay and connect it
		dic = { "on_button1_clicked" : self.button1_clicked,
			"on_MainWindow_destroy" : gtk.main_quit }
		self.wTree.signal_autoconnect(dic)
	
	def button1_clicked(self, widget):
		print "Hello World!"
		
if __name__ == "__main__":
	hwg = HellowWorldGTK()
	gtk.main()


In my form I have the signal linked to call the right functions, am I doing something obviously wrong?

Also noticing I don't have this XML file, I guess Glade didn't make it when I saved my .glade?

Edited by Analog, 26 June 2010 - 10:30 AM.


#13 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 26 June 2010 - 01:42 PM

You want to do something like this for loading from an xml file:

b = gtk.Builder()
b.add_from_file("MainWindow.xml")
Where Mainwindow.xml is the exported xml file from Glade. I forget how to do that off the top of my head, and am not on a windows machine :(. You'll have to play around for that :p.

Then, you can use something like this to get a handler to the button control or whatever you want:

b.get_object("startbutton").connect("clicked", startClicked)
You're connecting the "clicked" signal to the startClicked function. The startClicked function can do whatever you want then and will be called whenever the button named "startbutton" is clicked. You can name controls in Glade :).

Hope that helps :D.

#14 Analog

Analog
  • 13 posts

Posted 26 June 2010 - 04:58 PM

You want to do something like this for loading from an xml file:

b = gtk.Builder()
b.add_from_file("MainWindow.xml")
Where Mainwindow.xml is the exported xml file from Glade. I forget how to do that off the top of my head, and am not on a windows machine :(. You'll have to play around for that :p.

Then, you can use something like this to get a handler to the button control or whatever you want:

b.get_object("startbutton").connect("clicked", startClicked)
You're connecting the "clicked" signal to the startClicked function. The startClicked function can do whatever you want then and will be called whenever the button named "startbutton" is clicked. You can name controls in Glade :).

Hope that helps :D.


It seems Glade by default exports as .glade. Is this considered an xml? I believe I read around that it is a form of xml with the new glade, but am unsure. Will try this out and get back to you. Thanks.




#15 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 26 June 2010 - 05:27 PM

It seems Glade by default exports as .glade. Is this considered an xml? I believe I read around that it is a form of xml with the new glade, but am unsure. Will try this out and get back to you. Thanks.

Possibly... try using .glade as the extension in the add_from_file call.

Or just open the .glade file in a text editor and see if it is xml :p

#16 Analog

Analog
  • 13 posts

Posted 26 June 2010 - 06:24 PM

Turns out it was an xml. But this produces a new problem. Now I have my code

import sys
import gtk
import gtk.glade


def __init__(self):
		
	#Set the Glade file
	b = gtk.Builder()
	b.add_from_file("Derp.xml")
         
		
	#Create the connections
	b.get_object("button1").connect("clicked", button1_clicked)
		
	
def button1_clicked(self, widget):
	print "Hello World!"
	#function for on click	

And this causes the error that gtk and gtk.glade don't exist on the import lines. Hmm. Am I pointing it in the wrong direction? I feel like I'm almost there...

Edited by Analog, 26 June 2010 - 06:28 PM.


#17 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 26 June 2010 - 07:57 PM

You are almost there! I think you've just not installed the python bindings for gtk and glade... Looking through my code, it looks like I didn't have to import glade, but gobject. Their api could have changed though so I'm not sure...

I think you have to install pygtk: http://www.pygtk.org/

#18 Analog

Analog
  • 13 posts

Posted 26 June 2010 - 09:17 PM

Excellent! Now it's almost working. Now with the code


import sys
import gobject
import gtk
import gtk.glade
import pygtk
pygtk.require("2.0")

class HellowWorldGTK:
	def __init__(self):
		
		#Set the Glade file
		b = gtk.Builder()
		b.add_from_file("Derp.glade")
	     
		
		#Create the connections
		b.get_object("button1").connect("clicked", button1_clicked)
		
	
	def button1_clicked(self, widget):
		print "Hello World!"
		#function for on click	

if __name__ == "__main__":
        hwg = HellowWorldGTK()
        gtk.main()

It brings me to an error global name 'button1_clicked' is not defined, and something about the hwg = HellowWorldGTK part.

But the form pops up for a second before the error! I was excited.

#19 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 26 June 2010 - 11:11 PM

You're almost there :D.

The reason why the error "error global name 'button1_clicked' is not defined" comes up is because it's after the init function :p. Python scans the file top down so when it gets to __init__, it knows nothing about this button1_clicked function. Just move it above init :p.


As for the second error, could you paste it here?

#20 Analog

Analog
  • 13 posts

Posted 26 June 2010 - 11:28 PM

You're almost there :D.

The reason why the error "error global name 'button1_clicked' is not defined" comes up is because it's after the init function :p. Python scans the file top down so when it gets to __init__, it knows nothing about this button1_clicked function. Just move it above init :p.

As for the second error, could you paste it here?


The two errors I still get, even after replacing the code above init are:

File "derp.py.txt", line 22, in <module>
hwg = HellowWorldGTK()

File "derp.py.txt", line 18, in __init__
b.get_object("button1").connect("clicked", button1_clicked)
NameError: global name 'button1' is not defined

Edited by Analog, 26 June 2010 - 11:35 PM.


#21 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 26 June 2010 - 11:42 PM

The two errors I still get, even after replacing the code above init are:

File "derp.py.txt", line 22, in <module>
hwg = HellowWorldGTK()

File "derp.py.txt", line 18, in __init__
b.get_object("button1").connect("clicked", button1_clicked)
NameError: global name 'button1' is not defined

Could you paste the entire source again?

#22 Analog

Analog
  • 13 posts

Posted 26 June 2010 - 11:46 PM

Could you paste the entire source again?


import sys
import gobject
import gtk
import gtk.glade
import pygtk
pygtk.require("2.0")

class HellowWorldGTK:
	def button1_clicked(self, widget):
		print "Hello World!"
		#function for on click	
		
	def __init__(self):
		#Set the Glade file
		b = gtk.Builder()
		b.add_from_file("Derp.glade")
    	#Create the connections
		b.get_object("button1").connect("clicked", button1_clicked)

if __name__ == "__main__":
 	g = HellowWorldGTK()
 	gtk.main()

This changes the error to lines 20 and 18 respectively.

If I move the button1_clicked def outside of the class it loads the GUI, but then gives me the error:
TypeError: button1_clicked() takes exactly 2 arguments (1 given)

Edited by Analog, 27 June 2010 - 12:16 AM.


#23 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 27 June 2010 - 12:23 AM

Ah right, so the way you're connecting button1_clicked, button1_clicked is said to exist in the global scope, when you have defined it in the HellowWorldGTK class. You can change the connect line to something like this:
b.get_object("button1").connect("clicked", HellowWorldGTK.button1_clicked)
Note the HellowWorldGTK in front of button1_clicked. You can also move the button1_clicked function out of the HellowWorldGTK class, but then you should remove the self argument on the button1_clicked function. This is because functions bound to a class are passed the self argument implicitly, and global functions (functions outside of a class) are not passed the self argument.

#24 Analog

Analog
  • 13 posts

Posted 27 June 2010 - 12:33 AM

Ah right, so the way you're connecting button1_clicked, button1_clicked is said to exist in the global scope, when you have defined it in the HellowWorldGTK class. You can change the connect line to something like this:

b.get_object("button1").connect("clicked", HellowWorldGTK.button1_clicked)
Note the HellowWorldGTK in front of button1_clicked. You can also move the button1_clicked function out of the HellowWorldGTK class, but then you should remove the self argument on the button1_clicked function. This is because functions bound to a class are passed the self argument implicitly, and global functions (functions outside of a class) are not passed the self argument.


Ah, I see. How interesting. This is exciting, this brings the form up, but when I click the button, I get the error:
TypeError: unbound method button1_clicked() must be called with HellowWorldGTK instance as first argument (got Button instance instead).

What does this refer to? Sorry for all of the errors, but once I get this solved I am good to go forever basically. Thanks for sticking with me.:)

EDIT: After playing around, I found that if I bring the def button1_clicked(widget) outside of the class, and then take out HellowWorldGTK in front of button1_clicked, it seems to work just fine, it prints Hello World! in the console. Now to find out how to make a message box. :)

Edited by Analog, 27 June 2010 - 12:40 AM.


#25 Hydrogen

Hydrogen
  • Neocodex Co-Founder

  • 22213 posts


Users Awards

Posted 27 June 2010 - 12:55 AM

EDIT: After playing around, I found that if I bring the def button1_clicked(widget) outside of the class, and then take out HellowWorldGTK in front of button1_clicked, it seems to work just fine, it prints Hello World! in the console. Now to find out how to make a message box. :)

Indeed, that was the problem :p. Congrats! Your first GUI program :D.


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users