-1

I have an issue where an extra GUI is appearing when I run Client.py. I think this is because I set myMenu = Toplevel() on the 9th line of Menu.py, but if I don't include that there, before line 10, line 10 throws an error (and the menu GUI never pops up because of it):

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Pat\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
    return self.func(*args)
  File "C:\Users\Pat\Documents\GitHub\DunderMifflinSales\DunderMifflinClient.py", line 48, in _login_btn_clicked
    Menu.create_menu()
  File "C:\Users\Pat\Documents\GitHub\DunderMifflinSales\Menu.py", line 53, in create_menu
    mf = MenuFrame(root)
  File "C:\Users\Pat\Documents\GitHub\DunderMifflinSales\Menu.py", line 11, in __init__
    mainframe = ttk.Frame(myMenu,padding="3 3 12 12")
NameError: name 'myMenu' is not defined

I am new to both python and Tkinter, and would like an explanation as to what I'm doing wrong and what I can do to fix it. Thank you!

Client.py:

import socket
from tkinter import *
import tkinter.messagebox as tm
from tkinter import ttk
import Menu

serverName = 'localhost'
serverPort = 12000
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)


class LoginFrame(Frame):

    def __init__(self, master):
        super().__init__(master)

        self.label_1 = Label(self, text="Username")
        self.label_2 = Label(self, text="Password")

        self.entry_1 = Entry(self)
        self.entry_2 = Entry(self, show="*")

        self.label_1.grid(row=0, sticky=E)
        self.label_2.grid(row=1, sticky=E)
        self.entry_1.grid(row=0, column=1)
        self.entry_2.grid(row=1, column=1)

        self.logbtn = Button(self, text="Login", command = self._login_btn_clicked)
        self.logbtn.grid(columnspan=2)

        self.pack()


    def _login_btn_clicked(self):

        username = self.entry_1.get()
        clientSocket.sendto(username.encode('UTF-8'),(serverName, serverPort))

        password = self.entry_2.get()
        clientSocket.sendto(password.encode('UTF-8'),(serverName, serverPort))

        message, address = clientSocket.recvfrom(1024)
        message = message.decode('UTF-8')

        if message == "200 OK":
            Menu.create_menu()

        else:
            tm.showinfo("Login error", message)


def main():
    root = Tk()
    root.title("Dunder Mifflin GUI")
    root.geometry('{}x{}'.format(270, 80))
    lf = LoginFrame(root)
    root.mainloop()

if __name__ == "__main__":
    main()

Menu.py:

from tkinter import *
from tkinter import ttk

class MenuFrame(Frame):

    def __init__(self, master):
        super().__init__(master)

        myMenu = Toplevel()

        mainframe = ttk.Frame(myMenu,padding="3 3 12 12")
        mainframe.grid(column = 0, row = 0, sticky = (N, W, E, S))
        mainframe.columnconfigure(0, weight = 1)
        mainframe.rowconfigure(0, weight = 1)

        name = "John"
        sales = StringVar()
        moreSales = StringVar()
        sales.set("1")

        welcome = "Welcome, " + name + "!"

        sales_entry = ttk.Entry(mainframe, width = 7, textvariable = moreSales)

        ttk.Label(mainframe, text = welcome).grid(column = 2, row = 1, sticky = W)

        ttk.Label(mainframe, text = "Current Sales:").grid(column = 1, row = 2, sticky = W)
        ttk.Label(mainframe, textvariable = sales).grid(column = 2, row = 2, sticky = (E))
        ttk.Label(mainframe, text = "sales").grid(column = 3, row = 2, sticky = W)

        ttk.Label(mainframe, text = "Add Sales").grid(column = 1, row = 3, sticky = W)
        sales_entry.grid(column = 2, row = 3, sticky = (W, E))
        ttk.Button(mainframe, text = "Add", command = MenuFrame.add(sales, moreSales)).grid(column = 3, row = 3, sticky = W)

        ttk.Button(mainframe, text = "Log Out", command = MenuFrame.logout).grid(column = 2, row = 4, sticky = W)


    def add(sales, moreSales):

        try:
            value1 = int(sales.get())
            value2 = int(moreSales.get())
            sales.set(value1 + value2)
        except ValueError:
            pass

    def logout():
        myMenu.destroy()

def create_menu():
    root = Tk()
    root.title("Dunder Mifflin GUI")
    mf = MenuFrame(root)
    root.mainloop()
    root.destroy()


if __name__ == "__create_menu__":
    create_menu()
Pat Mulvihill
  • 53
  • 1
  • 12
  • 1
    in error message you have `root` in line `mainframe = ttk.Frame(root,...)` but in `Menu.py` you have `myMeny` in `mainframe = ttk.Frame(myMenu, ...)` - are you sure you use correct file ? – furas Dec 07 '15 at 00:27
  • Sorry, I accidentally added an error that I was dealing with earlier. The correct error is now there, although the nature of the errors seem similar. – Pat Mulvihill Dec 07 '15 at 00:49

1 Answers1

1

The stacktrace in your question seems unrelated to the code in your question, because the stacktrace shows the code mf = Menu.MenuFrame(mymenu) but that code doesn't exist in the code you've posted.

Your code is creating an "extra GUI" because you are telling it to. You must only create a single instance of Tk, but you're creating two. You create one in Client.py (method main), and one in Menu.py (method create_menu).

The name commonly applied to an instance of Tk is root, because this is (and must be) the root of a hierarchy of widgets. You cannot have two roots to a tree.

Unrelated to the problem at hand, are you aware that if __name__ == "__create_menu__" will always be False?

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I am not aware of that. Can you explain to me how that function works? Also, I changed the `root = Tk()` in Menu.py to `root = Toplevel()` but that didn't seem to resolve the issue - two guis are still firing (one of which is completely empty). – Pat Mulvihill Dec 07 '15 at 00:47