-2

So this is my first Python GUI project utilizing tkinter. I come from a background in R.

I decided after a review of the documentation to create a class to handle the bulk of the work. The problem appears with my incrementer functions fwd() and bck(). If I do not call these functions in the following chunk of code:

class App:
def __init__(self, master):
    ....
    self.total = 2
    self.fwd()
    self.bck()

The output of the entire code is an empty tkinter frame.

On the other hand, if I do call them, the fwd() function works as one would expect, but every time I click the back button (command = bck()), a new and identical GUI will be attached directly to the bottom of my current GUI. If I click the back button again, another GUI will pop up behind the current GUI.

from tkinter import *
from tkinter import font
from tkinter import filedialog

class App: #I'm not typing what goes in this class, this way I can avoid issues with App(Frame), etc. DUCKTYPE!
def __init__(self, master):
    self.frame = Frame(master)
    self.frame.pack()
    self.master = master
    master.title("PyCCI Caste")
    self.total = 2
    self.fwd() #Need to call these at the beginning otherwise the window is minimized??? No idea why.
    self.bck() #The back button creates a duplicate window...

## +Incrementer
def fwd(self):
    self.total += 1
    print(self.total)

## -Incrementer THIS CREATES A SECOND PANED WINDOW, WHY?!
def bck(self):
    self.total += -1
    if self.total < 3:
        self.total = 2
    print(self.total)


#Body
    self.k1 = PanedWindow(self.frame, #Note: if this is not self.frame, the error: 'App' object has no attribute 'tk' is thrown
                          height=500,
                          width=750,
                          orient = VERTICAL)
    self.k1.pack(fill=BOTH, expand = 1)
    self.titlefont = font.Font(size = 12,
                               weight = 'bold')
    self.boldfont = font.Font(size=8,
                              weight = 'bold')
    self.textfont = font.Font(family = 'Arial',
                              size = 10)

#Title
    self.title = PanedWindow(self.k1)
    self.k1.add(self.title, padx = 10, pady = 10)
    Label(self.title, text = "Chronic Critically Ill Patient GUI",
          font = self.titlefont,
          fg="darkslateblue").pack()

#Top row open csv window & button
    self.k2 = PanedWindow(self.k1)
    self.k1.add(self.k2)
    self.openbutton = Button(self.k2,
                             text = "Open CSV")#, command = openfile())
    self.openbutton.pack(side = LEFT,
                         padx = 30)

#Panes below buttons
    self.k3 = PanedWindow(self.k1)
    self.k1.add(self.k3)
    self.leftpane = PanedWindow(self.k3)
    self.k3.add(self.leftpane,
                width = 400,
                padx = 30,
                pady = 25,
                stretch = "first")
    self.separator = PanedWindow(self.k3,
                                 relief = SUNKEN)
    self.k3.add(self.separator,
                width=2,
                padx=1,
                pady=20)
    self.rightpane = PanedWindow(self.k3)
    self.k3.add(self.rightpane,
                width = 220,
                padx = 10,
                pady = 25,
                stretch = "never")

#Left pane patient note text frame doo-diddly
    self.ptframe = LabelFrame(self.leftpane,
                              text = "Medical Record",
                              font = self.boldfont,
                              padx = 0,
                              pady=0,
                              borderwidth = 0)
    self.ptframe.pack()
    Label(self.ptframe,
          text = "patient # of ##").pack()

#Incrementer buttons
    self.buttonframe = Frame(self.ptframe)
    self.buttonframe.pack()
    self.buttonframe.place(relx=0.97, anchor = NE)
    #Back Button
    self.button1 = Button(self.buttonframe, text = 'Back', width = 6, command = self.bck)
    self.button1.grid(row = 0, column = 0, padx = 2, pady = 2)
    #Next Button
    self.button2 = Button(self.buttonframe, text = 'Next', width = 6, command = self.fwd)
    self.button2.grid(row = 0, column = 2, padx = 2, pady = 2)

#Scrollbar!
    self.ptscroll = Scrollbar(self.ptframe)
    self.ptscroll.pack(side = RIGHT, fill = Y)
    self.pttext = Text(self.ptframe,
                       height=300,
                       width=400,
                       wrap=WORD,
                       font=self.textfont,
                       spacing1=2,
                       spacing2=2,
                       spacing3=3,
                       padx=15,
                       pady=15)
    self.pttext.pack()
    self.ptscroll.config(command=self.pttext.yview)
    self.pttext.config(yscrollcommand=self.ptscroll.set)

#Checkbuttons
    self.checkframe = LabelFrame(self.rightpane, text="Indicators",
                                 font=self.boldfont,
                                 padx = 10,
                                 pady = 10,
                                 borderwidth=0)
    self.checkframe.pack()
    self.check1 = Checkbutton(self.checkframe, text="Non-Adherence")
    self.check1.grid(row = 1,
                     column = 0,
                     sticky = W)

root = Tk()
app = App(root) ## apply the class "App" to Tk()

### Menu stuff does not need to be part of the class
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Open CSV")#, command=openfile)
menubar.add_cascade(label="File", menu=filemenu)
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label="About")#, command=about)
menubar.add_cascade(label="Help", menu=helpmenu)
root.config(menu=menubar)
root.mainloop()

What do you folks think? If I'm missing any pertinent information here, please let me know. The difficulty I'm having is that I don't know what I don't know about Python/Tkinter yet.

Thanks, I really appreciate any insight and direction.

Solved (thanks Bryan Oakley & TigerhawkT3): Due to Python's use of indentation as part of its syntax, I had created a function bck() which, when called, includes the code for the entirety of the rest of the GUI. To solve this problem after it was pointed out, I drew heavily from: Python def function: How do you specify the end of the function?

Community
  • 1
  • 1
Phantom Photon
  • 768
  • 2
  • 10
  • 20
  • 1
    Please make a complete minimal example... – Eric Levieil Jun 08 '15 at 21:09
  • 1
    You have a few linefeeds after printing `self.total` within `bck`, but then the function continues, doing all manner of fun stuff. Fix your indentation (don't forget the syntax error on line 6). – TigerhawkT3 Jun 08 '15 at 21:48
  • 1
    Your `bck` function is clearly creating new widgets each time it is called. Why do you think it should do otherwise? – Bryan Oakley Jun 08 '15 at 23:24
  • Why does the `bck` function make new widgets and the `fwd` function doesn't? – Phantom Photon Jun 08 '15 at 23:49
  • 1
    @PGT121: because `fwd` has two lines of code, neither of which creates a widget, and `bck` has a couple dozen lines of code including many lines of code that creates widgets. Perhaps you have an indentation error? Is the code after `#Panes below buttons` intended to be part of `bck`? It is, based on how you've indented the code. – Bryan Oakley Jun 09 '15 at 00:37

1 Answers1

1

You appear you have a simple indentation error. It seems like you intend for bck to have four lines of code, but because almost all of the remaining code is indented the same, it is all considered to be part of bck.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thanks so much, Bryan. I see now, and I really appreciate your patience. I apologize to others for this lousy question but, as I said in the original post, I am new to Python and I don't know what I don't know. – Phantom Photon Jun 09 '15 at 14:22