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!

Recommended Answers

All 9 Replies

NVM fixed

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()

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?

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:

#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)

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

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

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

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

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?

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

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!

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.