i need some help writing a GUI for the program i'm making. it is a simple text-based number-guessing game and i would like to have the prompts displayed in a nice window.

i would also like to have the "number_guesses" and the "guess_list" variables displayed off to the right of the prompts, and get updated dynamically.

heres my code so y'all can understand what i'm talking about:

import random, time

number = random.randint(1,50)
running = True
guess_str = "Guess the number I'm thinking of between 1 and 50, then press enter: "
number_guesses = 0
play_again = ""
yes_in = ["true", "yes", "t", "y", "affirmitive"]
guess_list = []

def play():
    global number, running, guess_str, number_guesses
    while running:
        guess = raw_input(guess_str)
        try:
            guess = int(guess)
            if number_guesses == 10:
                print "Sorry, you lost!"
		running = False
            elif guess == number:
                number_guesses += 1
                print "Congrats, you guessed it! It took you", number_guesses, "guesses."
                running = False
            elif number < guess < (number + 15):
                number_guesses += 1
                guess_str = "Your guess was a little high... Guess again: "
                print "Guesses left: ", (10 - number_guesses)
                if guess in guess_list:
                    guess_str = "You have already guessed that. Try again: "
                elif guess not in guess_list:
                    guess_list.append(guess)
                print "You have guessed: ", guess_list
            elif number > guess > (number - 15):
                number_guesses += 1
                guess_str = "Your guess was a little low... Guess again: "
                print "Guesses left: ", (10 - number_guesses)
                if guess in guess_list:
                    guess_str = "You have already guessed that. Try again: "                    
                elif guess not in guess_list:
                    guess_list.append(guess)
                print "You have guessed: ", guess_list
            elif guess < (number + 15):
                number_guesses += 1
                guess_str = "Your guess was very low... Guess again: "
                print "Guesses left: ", (10 - number_guesses)
                if guess in guess_list:
                    guess_str = "You have already guessed that. Try again: "
                elif guess not in guess_list:
                    guess_list.append(guess)
                print "You have guessed: ", guess_list
            else:
                number_guesses += 1
                guess_str = "Your guess was very high... Guess again: "
                print "Guesses left: ", (10 - number_guesses)
                if guess in guess_list:
                    guess_str = "You have already guessed that. Try again: "
                elif guess not in guess_list:
                    guess_list.append(guess)
                print "You have guessed: ", guess_list
        except:
            guess_str = "The value you inserted is not an integer. Try again: "
            continue
            
def reset():
    global number, running, guess_str, number_guesses, play_again
    number = random.randint(1,50)
    running = True
    guess_str = "Guess the number I'm thinking of between and 50, then press enter: "
    number_guesses = 0
    guess_list = []
    play_again = str(raw_input("Play again? (yes/no, then enter) "))

def playAgain():
    global play_again, yes_in
    if play_again.lower()in yes_in:
        play_total()
    else:
        print "Thanks for playing!"
        time.sleep(1)
        quit()

def play_total():
    play()
    reset()
    playAgain()

play_total()

thanks for any tips, and know that i will likely not know what you're talking about, because i don't have any experience with wxPython.
billy

btw: tips on the script in general are welcome!

Recommended Answers

All 50 Replies

Okay, thats simple enough. What you would be looking at is using wx.StaticText for all of your displaying text needs.
http://www.wxpython.org/docs/api/wx.StaticText-class.html
This you can update with the SetValue("Value") function.

If you ever need user input you can use wx.Button
http://www.wxpython.org/docs/api/wx.Button-class.html

Or a wx.TextCtrl, this is basically like an input box. Kinda like the one you type your forum responses into.
You can get its data by using the GetValue() function
http://www.wxpython.org/docs/api/wx.TextCtrl-class.html

Hope that helps you on your way :)

I suggest downloading the 'Docs and Demos' along with your wxPython install, as it gives you a great launch pad to start writing your own GUIs by giving you sample code of almost every single type of wx object.

It's ridiculously helpful when starting wxPython.

commented: Everyone (including me) seems to agree, so +rep :) +17

I suggest downloading the 'Docs and Demos' along with your wxPython install, as it gives you a great launch pad to start writing your own GUIs by giving you sample code of almost every single type of wx object.

It's ridiculously helpful when starting wxPython.

That is in fact a great idea, that and the api are powerful learning tools.

Docs and demos are a certainly great resource.

The wx demos sugg because there is too much code bloat! You may be able to figure it out anyway.

BTW, your console code could stand major improvement.

Yeah they do, but what i do is usually find out what i need to use with the demo. Fiddle around a little bit with the declaration of the object i am using just to get a little used to it. Then i look at the api, i find that is the best learning tool for wxPython, you just have to try a little sometimes. :)

thanks for the tips, guys, i'll check it out.

@sneekula: what do you suggest for my console code? examples?

oh, by the way, how would i make the text clear off the screen after each input?

Use this to clear the screen on a console program:

import sys
# on Windows
os.system("CLS") 
# on Linux
os.system('clear')

Also for my taste avoid using globals, they can get you into conflicts. You can generally pass them to and from functions in the arguments.

Do you want to use wxPython because you want to learn it? The Tkinter GUI toolkit is somewhat simpler to use, but then getting into GUI programming is somewhat of a steep learning curve anyway.

thanks, Ene Uran. the main reason is because i heard that it would be good for writing a GUI.

Well, wxPython is a very powerful GUI toolkit, well worth learning. It's parent is wxWindows written in C++, this will show up in some of the manuals. A lot of people on this forum use it, so you should get lots of help. Just keep asking questions.

ok, ive come up with a question:
if i want to create a simple text enter box thing (like on google or something), what style would i use for TextCrtl? or wouldnt i use that?

and another:
what do i put here?
i never understand how to read apis. :(

class MainWindow(wx.Frame):
    def __init__(self,parent,id,title):
        wx.Frame.__init__(self,parent,wx.ID_ANY,title,size = (1000,500), style= wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE )
        self.control = wx.StaticText(WHAT DO I PUT HERE?)
        self.Show(True)

ok, answered the second question myself.
but: how do i set position of static text?

ok, all questions i have had have been answered by good ol' youtube, but now i have a new one:
how do you set "padding" (like with css) for a static text thing?

never mind again, already figured it out, and learned a lesson in figuring it out myself. :icon_redface:

You are making good progress on your own!

Here is a typical example for some widgets you are interested in:

# a wxPython example for label widgets (wx.StaticText) 
# and an entry or edit widget (wx.TextCtrl)

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, mytitle):
        # -1 = wx.ID_ANY (wxPython will pick a unique id value)
        wx.Frame.__init__(self, parent, -1, mytitle, 
            pos=(100, 150), size=(300, 150))
        self.SetBackgroundColour("yellow")

        s = "Enter your name below:"
        label = wx.StaticText(self, -1, s)
        self.edit = wx.TextCtrl(self, -1, value="") #, size=(200, 20))
        # respond to enter key when focus is on self.edit
        self.edit.Bind(wx.EVT_TEXT_ENTER, self.onEnter)
        self.result = wx.StaticText(self, -1)

        # position your widgets using a box sizer
        # (line up in a vertical stack)
        # wx.ALL --> widget has specified border on all sides
        # wx.EXPAND --> widget will expand to fit resized frame
        sizer_v = wx.BoxSizer(wx.VERTICAL)
        sizer_v.Add(label, 0, flag=wx.ALL|wx.EXPAND, border=4)
        sizer_v.Add(self.edit, 0, flag=wx.ALL|wx.EXPAND, border=4)
        sizer_v.Add(self.result, 0, flag=wx.ALL|wx.EXPAND, border=8)
        self.SetSizer(sizer_v)
        
        # put the cursor in the edit widget
        self.edit.SetFocus()
        
    def onEnter(self, event):
        """the enter key has been pressed in self.edit"""
        name = self.edit.GetValue()
        s = "You entered the name: " + name
        self.result.SetLabel(s)
        

app = wx.App(0)
MyFrame(None, 'testing wx.TextCtrl').Show()
app.MainLoop()

Wow, i must say i am impressed. A lot of people just sit around lazily for answers, its great that your pursuing them yourself. It will certainly lead to you learning a lot faster ;)

ok, all questions i have had have been answered by good ol' youtube,

What?? Are there really wxPython programming tutorials on youtube or something?

just one set that i've found. it goes over boxsizers and event handling, pretty basic stuff.

lol. i didn't realize til today that the tutorials i've been watching are paulthom's tutorials. thanks!

ok. i'm having some problems.
heres the code:

class MainWindow(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None,title="Guessing Game",size = (500,200))
            self.answer = wx.TextCtrl(self,style=wx.PROCESS_ENTER)
            self.answer.Bind(wx.EVT_TEXT_ENTER,self.compare)
    def compare(self,event):
        global number
        guess = self.answer.GetValue()
        try:
            int(guess)
            if guess == number:
                self.prompts.SetValue("Yay!")
                self.answer.SetValue('You Win!')
            else:
                self.prompts.SetValue("Nope.")
                self.answer.SetValue('')
        except TypeError:
            self.prompts.SetValue("Not an integer")

    def reset(self,event):
        global number
        number = 2
        self.prompts.SetValue("Guess the number I'm thinking of!")

no matter what you enter in 'answer', it always says nope, or doesn't change when you put in a non-integer. any ideas?

ok, i fixed that, but only by doing this:

def compare(self,event):
        global number
        guess = self.answer.GetValue()
        if guess == str(number):
            self.prompts.SetValue("Yay!")
            self.answer.SetValue('You Win!')
        else:
            self.prompts.SetValue("Nope.")
            self.answer.SetValue('')

which is the same as last time, but emitting the try part and just checking the guess variable to the number variable in string form. but that doesn't work for what i want to do later. how do i use try properly in this situation?

ok. nevermind. got that all sorted out. i'm having a problem with using randint for the number you have to guess, though. it just crashes as soon as you start it when you add that line to the code.

lol, the only reason this is "hot" is because i keep asking questions and answering them. i still haven't answered the previous question, but here's a new one:
how do i set the "padding" of a StaticText object? right now, the text in my static text is just at the edge of the page and doesn't look very good.
alternatively, could i set "padding" for the entire frame?

ok. here's my beta code:

import wx, random

class MainWindow(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None,title="Guessing Game",size = (500,200))
        self.SetBackgroundColour("white")
        
        #PARTS
        self.displayprompt = wx.BoxSizer(wx.VERTICAL)
        self.answer = wx.TextCtrl(self,style=wx.PROCESS_ENTER)
        self.prompts = wx.TextCtrl(self,style = wx.TE_READONLY)
        self.info = wx.StaticText(self)
        
        #ORGANIZING
        self.displayprompt.Add(self.info,proportion=1,flag= wx.EXPAND)
        self.displayprompt.Add(self.prompts,proportion=0,flag= wx.EXPAND)
        self.displayprompt.Add(self.answer,proportion=0,flag = wx.EXPAND)
        
        #BINDING
        self.answer.Bind(wx.EVT_TEXT_ENTER,self.compare)
        
        #SHOWING AND CALLING
        self.SetSizer(self.displayprompt)
        self.Show(True)
        self.reset()
#FUNCTIONS
    def reset(self):
        global number, guesses, number_guesses
        number = 2
        self.prompts.SetValue("Guess the number I'm thinking of!")
        self.info.SetLabel("You have guessed 0 times")
        guesses = []
        number_guesses = 0
        
    def compare(self,event):
        global number, guesses, number_guesses
        guess = self.answer.GetValue()
        try:
            if int(guess) == number:
                self.prompts.SetValue("Yay!")
                number_guesses += 1
                self.info.SetLabel("YOU WIN!\nYou guessed " + str(number_guesses) + " time(s).")
                self.answer.SetValue('')
                wx.FutureCall(500, self.playAgain)
            else:
                self.prompts.SetValue("Nope.")
                number_guesses += 1
                self.info.SetLabel("You have guessed " + str(number_guesses) + " time(s).")
                self.answer.SetValue('')
        except TypeError:
            self.prompts.SetValue("Invalid Entry")
            self.answer.SetValue('')

    def playAgain(self):
        msgbox = wx.MessageDialog(self,message="Play Again?",style = wx.ICON_QUESTION|wx.OK|wx.CANCEL)
        if msgbox.ShowModal() == wx.ID_CANCEL:
            self.Destroy()
        elif msgbox.ShowModal() == wx.ID_OK:
            msgbox.Destroy()
            self.reset()

app = wx.App(redirect=False)
frame = MainWindow()
app.MainLoop()

any suggestions? still havent figured out padding or randint, but ill keep working. another thing is that when you win, after the message box pops up, you have to click ok twice to get it to work.
im also working on displaying what you have guessed in the "info" section. any ideas as to how to do this?

oh, by the way: later scripts will tell you if you have guessed to high or too low.

Okay, wow. It's really awesome that you're learning how easy it is to code with Python and wx and also that you're figuring out problems as quickly as your coming up with questions.

But for our sake, can you give us a "status update": Current questions and any related info
[ Pretty formatting helps us read ;) ]

It's just that this thread has now grown to 3 pages and it's difficult to tell which questions you've answered yourself or not.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.