954,549 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Can't get grid to work!

What am I doing wrong, I've done it before!

class Main:
    def __init__(self, master):
        self.master = master
        self.master.title('Role Playing Form V1.0')
        self.master.geometry('300x250+350+450')
        self.master.mainloop()
        self.cmdCreate = Button(self.master, text='Create Character', command=self.create)
        self.cmdCreate.grid(row=0)
    def create(self):
        pass
root = Tk()
main=Main(root)


the button doesn't appear!

chris99
Junior Poster
118 posts since Sep 2006
Reputation Points: 10
Solved Threads: 0
 

NVM fixed

chris99
Junior Poster
118 posts since Sep 2006
Reputation Points: 10
Solved Threads: 0
 

Just in case others may wonder, you put the event loop mainloop() in the wrong place:

from Tkinter import *

class Main:
    def __init__(self, master):
        self.master = master
        self.master.title('Role Playing Form V1.0')
        self.master.geometry('300x250+350+450')
        #self.master.mainloop()  #!!!!!!!!!!
        self.cmdCreate = Button(self.master, text='Create Character', command=self.create)
        self.cmdCreate.grid(row=0)
    def create(self):
        pass

root = Tk()
main=Main(root)
# put event loop here
root.mainloop()
bumsfeld
Nearly a Posting Virtuoso
1,445 posts since Jul 2005
Reputation Points: 404
Solved Threads: 184
 

Another problem. I can't write to an existing file. I want it to create a file with the characterName, and read the same file again. However it just creates a new file with a blank title, and writes the data there. Here's the code:

#Role Playing Form.py
from Tkinter import *
global Name
global className
class Main:
    def __init__(self, master):
        self.master = master
        self.master.title('Role Playing Form V1.0')
        self.master.geometry('250x100+350+450')
        self.cmdCreate = Button(self.master, text='Create Character', command=self.create)
        self.cmdCreate.grid(row=0)
        self.cmdDelete = Button(self.master, text='Delete Character', command=self.delete)
        self.cmdDelete.grid(row=1)
        self.cmdLoad = Button(self.master, text='Load Character', command=self.load)
        self.cmdLoad.grid(row=2)
        self.master.mainloop()
    def create(self):
        nameCreate()
    def delete(self):
        pass
    def load(self):
        pass
#Brings up a dialog box for putting the name in.
#The enter button creates a file with name.txt for the title.
#This will be used to store data for that character.
class nameCreate:
    global Name
    def __init__(self):
        self.nameInput = Toplevel(root)
        self.nameInput.title('Name of Character?')
        self.nameInput.geometry('300x100+350+450')
        self.lblName = Label(self.nameInput, text='Enter Name Here')
        self.lblName.grid(row=0)
        self.entName = Entry(self.nameInput)
        self.entName.grid(row=0, column=1)
        self.cmdName = Button(self.nameInput, text='Enter', command=self.enter)
        self.cmdName.grid(row=1)
    def enter(self):
        Name = self.entName.get()
        print "Character Name:",Name
        fileChar = open('Character Data\ '+Name+'.txt',"w")
        classCreate()
        self.nameInput.destroy()
class classCreate:
    global className
    global Name
    def __init__(self):
        self.classChoose = Toplevel(root)
        self.classChoose.title('Choose your Class')
        self.classChoose.geometry('300x200+300+400')
        self.labelChoose = Label(self.classChoose, text="Select the class you wish to be")
        self.labelChoose.grid(row=0)
        self.listClass = Listbox(self.classChoose, height=4)
        self.listClass.grid(row=1)
        self.listClass.insert(END,"Warrior")
        self.confirm = Button(self.classChoose, text="Confirm", command=self.confirm)
        self.confirm.grid(row=2)
    def confirm(self):
        fileClass = open('ClassData.txt','r')
        for line in fileClass:
            classInfo=line.split(',')
            print Name
            print "This class's stats are:",classInfo
            className = classInfo[0]
            print "The name of the class is:",className
            fileChar = open('Character Data\ '+Name+'.txt','a')
            fileChar.writelines(className+',')
root = Tk()
main=Main(root)

Why is 'Name' changing to "", even though I called it global?

chris99
Junior Poster
118 posts since Sep 2006
Reputation Points: 10
Solved Threads: 0
 

Ok, well it writes correctly, but how do I make it write to the file on the next line down? And then read it?
The file will look like this:

Stats,Morestats,,,,,,,,
ExpGot,ExpToGain

How do I make it write to the next line after it has finished the initial one?

I also want it to read the line seperately from the firstHere's the code:

[php]#Role Playing Form.py
from Tkinter import *
#Define Global Variables
global Name
global CharHpMax
global CharHpCurrent
global CharMpMax
global CharMpCurrent
global CharStr
global CharDef
global CharMAtt
global CharMDef
global Currentexp
global Requiredexp
#Create the Start window
class Main:
def __init__(self, master):
torch=PhotoImage(file="C:\Python24\Python Progs\Role Playing Form\Images\Title Screen Flames.gif")
grave=PhotoImage(file="C:\Python24\Python Progs\Role Playing Form\Images\TitleScreenGraves.gif")
ankh=PhotoImage(file="C:\Python24\Python Progs\Role Playing Form\Images\TitleScreenAnkh.gif")
self.master = master
self.master.title('Role Playing Form V1.0')
self.master.geometry('250x250+350+450')
self.torchLabelL=Label(self.master, image=torch)
self.torchLabelL.grid(row=0, column=0)
self.cmdCreate = Button(self.master, text='Create Character', command=self.create)
self.cmdCreate.grid(row=0, column=1)
self.torchLabelR=Label(self.master, image=torch)
self.torchLabelR.grid(row=0, column=2)
self.graveLabelL=Label(self.master, image=grave)
self.graveLabelL.grid(row=1, column=0)
self.cmdDelete = Button(self.master, text='Delete Character', command=self.delete)
self.cmdDelete.grid(row=1, column=1)
self.graveLabelR=Label(self.master, image=grave)
self.graveLabelR.grid(row=1, column=2)
self.ankhLabelL=Label(self.master, image=ankh)
self.ankhLabelL.grid(row=2, column=0)
self.cmdLoad = Button(self.master, text='Load Character', command=self.load)
self.cmdLoad.grid(row=2, column=1)
self.ankhLabelR=Label(self.master, image=ankh)
self.ankhLabelR.grid(row=2, column=2)
self.master.mainloop()
def create(self):
nameCreate()
def delete(self):
pass
def load(self):
nameLoad()
#Brings up a dialog box for putting the name in.
#The enter button creates a file with name.txt for the title.
#This will be used to store data for that character.
class nameCreate:
def __init__(self):
self.nameInput = Toplevel(root)
self.nameInput.title('Name of Character?')
self.nameInput.geometry('300x100+350+450')
self.lblName = Label(self.nameInput, text='Enter Name Here')
self.lblName.grid(row=0)
self.entName = Entry(self.nameInput)
self.entName.grid(row=0, column=1)
self.cmdName = Button(self.nameInput, text='Enter', command=self.enter)
self.cmdName.grid(row=1)
def enter(self):
global Name
Name = self.entName.get()
print "Character Name:",Name
fileChar = open('Character Data\ '+Name+'.txt',"w")
classCreate()
self.nameInput.destroy()
class nameLoad:
def __init__(self):
self.nameInput = Toplevel(root)
self.nameInput.title('Name of Character?')
self.nameInput.geometry('300x100+350+450')
self.lblName = Label(self.nameInput, text='Enter Name Here')
self.lblName.grid(row=0)
self.entName = Entry(self.nameInput)
self.entName.grid(row=0, column=1)
self.cmdName = Button(self.nameInput, text='Load', command=self.load)
self.cmdName.grid(row=1)
def load(self):
global Name
global CharHpMax
global CharHpCurrent
global CharMpMax
global CharMpCurrent
global CharStr
global CharDef
global CharMAtt
global CharMDef
global Currentexp
global Requiredexp
Name = self.entName.get()
fileChar = open('Character Data\ '+Name+'.txt','r')
for line in fileChar:
classInfo=line.split(',')
CharHpMax = classInfo[1]
CharHpCurrent = classInfo[2]
CharMpMax = classInfo[3]
CharMpCurrent = classInfo[4]
CharStr = classInfo[5]
CharDef = classInfo[6]
CharMAtt = classInfo[7]
CharMDef = classInfo[8]
#Stuff about exp here assigned to the Current and Required
#exp stats
mainGame()

#Adds the stats based on what you selected in the form
class classCreate:
def __init__(self):
self.classChoose = Toplevel(root)
self.classChoose.title('Choose your Class')
self.classChoose.geometry('300x200+300+400')
self.labelChoose = Label(self.classChoose, text="Select the class you wish to be")
self.labelChoose.grid(row=0)
self.listClass = Listbox(self.classChoose, height=4)
self.listClass.grid(row=1)
self.listClass.insert(END,"Warrior")
self.confirm = Button(self.classChoose, text="Confirm", command=self.confirm)
self.confirm.grid(row=2)
def confirm(self):
global Name
global CharHpMax
global CharHpCurrent
global CharMpMax
global CharMpCurrent
global CharStr
global CharDef
global CharMAtt
global CharMDef
global Currentexp
global Requiredexp
fileClass = open('ClassData.txt','r')
for line in fileClass:
classInfo=line.split(',')
print "Name is:", Name
print "This class's stats are:",classInfo
className = classInfo[0]
CharHpMax = classInfo[1]
CharHpCurrent = classInfo[2]
CharMpMax = classInfo[3]
CharMpCurrent = classInfo[4]
CharStr = classInfo[5]
CharDef = classInfo[6]
CharMAtt = classInfo[7]
CharMDef = classInfo[8]
#sets the exp totals for the new game
Currentexp=0
Requiredexp=0
print "The name of the class is: ",className
print "The Character's max HP is: ",CharHpMax
print "The Character's Current Hp is: ",CharHpCurrent
print "The Character's max Mp is: ",CharMpMax
print "The Character's current Mp is: ",CharMpCurrent
print "The Character's Strength is: ",CharStr
print "The Character's Defence is: ", CharDef
print "The Character's Magic Power is: ", CharMAtt
print "The Character's Magic Resistance is: ", CharMDef
fileChar = open('Character Data\ '+Name+'.txt','a')
fileChar.writelines(className+','+CharHpMax+','+CharHpCurrent+','+CharMpMax+','+CharMpCurrent+','+CharStr+','+CharDef+','+CharMAtt+','+CharMDef+','+str(Currentexp)+','+str(Requiredexp))
mainGame()
self.classChoose.destroy()
class mainGame:
def __init__(self):
global Name
global CharHpMax
global CharHpCurrent
global CharMpMax
global CharMpCurrent
global CharStr
global CharDef
global CharMAtt
global CharMDef
self.gameMain = Toplevel(root)
self.gameMain.title('Role Playing Form V 1.0')
self.gameMain.geometry('400x500+350+400')
self.mainLabel = Label(self.gameMain, text="CHARACTER INFO:")
self.mainLabel.grid(row=0, column=0)
self.nameLabel = Label(self.gameMain, text="Name: "+Name)
self.nameLabel.grid(row=1, column=0)
self.HpLabel = Label(self.gameMain, text="HP: "+CharHpMax+"\ "+CharHpCurrent)
self.HpLabel.grid(row=2, column=0)
self.MpLabel = Label(self.gameMain, text="MP: "+CharMpMax+"\ "+CharMpCurrent)
self.MpLabel.grid(row=3, column=0)
self.StrLabel = Label(self.gameMain, text="Strength: "+CharStr)
self.StrLabel.grid(row=4, column=0)
self.DefLabel = Label(self.gameMain, text="Defence: "+CharDef)
self.DefLabel.grid(row=5, column=0)
self.MAttLabel = Label(self.gameMain, text="Magic Power: "+CharMAtt)
self.MAttLabel.grid(row=6, column=0)
self.MDefLabel = Label(self.gameMain, text="Magic Resistance: "+CharMDef)
self.MDefLabel.grid(row=7, column=0)
self.exitButton = Button(self.gameMain, text="Quit?", command=self.quitGame)
self.exitButton.grid(row=0, column=1)
def quitGame(self):
pass
root = Tk()
main=Main(root)
[/php]

And here's the format I'm hoping for for the text file:

Warrior,250,250,20,20,25,30,10,5
0,0

chris99
Junior Poster
118 posts since Sep 2006
Reputation Points: 10
Solved Threads: 0
 

You might want to start a new thread with the proper title. It will help you to get help!

vegaseat
DaniWeb's Hypocrite
Moderator
5,989 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

This is going to be a suggestion that's painful to implement up front, but that will save you a lot of pain on the flipside.

Your classes currently correspond to actions that you want to take: creating a name, creating a class, launching the game. The actual object in question, though, is the character. That should, IMO, be your one class. Then, you can create methods of that class to create the name, get his class, etc.

It would work something like this:

class Character(object):

  def __init__(self, app):  # app is the Tk() object you are linking to.
      self.window = app

  def create_name(self):
      root = Toplevel(self.window)
      ...  # create the modal dialog box for the name
      self.name = MyDialogReturnValue

  def create_class(self):
     root = Toplevel(self.window)
     ... # create the modal dialog box for the class
     self.class = MyDialogReturnValue


Now, why might one want to re-write the code in this way?

(1) In the end, it will clean away some of the fuzziness. The fact that you have massive numbers of global variables is an indication that there is difficulty getting the classes to interface with each other. That difficulty will compound as your game code progresses.

(2) Creating a character class will help you to simplify some of the problems like reading and writing from files. For example, the Character class can have a __str__() method that returns his proper representation. Then the "write to file" method becomes a piece of cake!

def __str__(self):
   s = "name: "+self.name
   s += "\nclass: "+self.className
   s +="\nMax HP: "+self.CharHpMax
   #etc.
   return s

def load(self, filename):
   f = open(filename, 'r')
   #read in all characteristics as strings
   # You might be able to do this as a loop; I'm just being lazy
   line = f.readline()
   _, self.name = line.split(":")
   self.name = self.name.strip()  # There ought to be a .= operator in Python!
   line = f.readline()
   _, self.className = line.split(":")
   self.className = self.className.strip() 
   line = f.readline()
   _, self.CharHpMax = line.split(":")
   self.CharHpMax = int(self.CharHpMax)
   ... # etc.
   
   f.close()

def save(self, filename):
   f = open(filename, 'w')
   f.write(str(self))
   f.close()


(3) There will come a day when you get the program working and want to allow more than one player to play. On that day, you will rejoice to have a character class that allows you to create *two or more* character objects, and *POOF*, you have a multi-player game. :cheesy:

I hope this is helpful rather than otherwise. Nevertheless, that's how I would refactor the code.

Regards,
Jeff

jrcagle
Practically a Master Poster
608 posts since Jul 2006
Reputation Points: 92
Solved Threads: 156
 

So, what would doing that basically be creating the Character class, and moving all the def statements into the class, all calling each other as needed, with the code being cut/pasted into each def? like the character class will create the start menu too?

chris99
Junior Poster
118 posts since Sep 2006
Reputation Points: 10
Solved Threads: 0
 

I've turned the whole game into one class, and it works. I'm having trouble getting an image to appear on the fightZone form, it doesn't give error messages, but it is not displaying the image.
Here's the .zip

Attachments Role_Playing_Form.zip (7.05KB)
chris99
Junior Poster
118 posts since Sep 2006
Reputation Points: 10
Solved Threads: 0
 

Avoid all those globals, you are using Python! If the class variables are global within the class use the prefix 'self.' this way they are part of the class instance when you switch characters.

If your gif files are in the current folder's subfolder use:
grave=PhotoImage(file=r".\Images\TitleScreenGraves.gif")

When you call function in the class, also prefix with 'self.' since this function is method in the class.

Your present thread title is missleading and has nothing to do with grid! Like vegaseat and others recommend, start a new thread and call it "Can't get class to work!". I won't look here any further!

bumsfeld
Nearly a Posting Virtuoso
1,445 posts since Jul 2005
Reputation Points: 404
Solved Threads: 184
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You