-1

EDIT: Thanks to @Osadhi Virochana Jayasinghe Si! Using global "vars" inside the buildwindow() function, makes them readable in the called button function. I also had to fix how to get the Values of the Checkbox and text Widget. Full Fixed code:

import tkinter as tk
import tkinter.scrolledtext as tkst
from PyQt5.QtWidgets import QApplication  # need to install PyQt5 or remove center() Function


def main_window():
    window = tk.Tk()
    window.title("New Entry")
    build_window(window)
    center(window)  # https://stackoverflow.com/questions/3352918/how-to-center-a-window-on-the-screen-in-tkinter

    window.mainloop()  # Main Loop, nothing runs after here on Gui


def center(toplevel):
    toplevel.update_idletasks()

    app = QApplication([])
    screen_width = app.desktop().screenGeometry().width()
    screen_height = app.desktop().screenGeometry().height()

    size = tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x'))
    x = screen_width/2 - size[0]/2
    y = screen_height/2 - size[1]/2

    toplevel.geometry("+%d+%d" % (x, y))


def build_window(window):
    global entry_name, entry_link, entry_xpath, chbox_active, entry_comment, box_var

    label_title = tk.Label(window, text="NEW ENTRY")
    label_name = tk.Label(window, text="Name:")
    entry_name = tk.Entry(window)
    label_link = tk.Label(window, text="Link:")
    entry_link = tk.Entry(window)
    label_xpath = tk.Label(window, text="XPath:")
    entry_xpath = tk.Entry(window)
    label_active = tk.Label(window, text="Active:")
    box_var = tk.IntVar()
    chbox_active = tk.Checkbutton(window, variable=box_var, text="Active")
    label_comment = tk.Label(window, text="Comment:")
    entry_comment = tkst.ScrolledText(window, width=40, height=4, font=("roboto", 8))
    botton_cancel = tk.Button(window, text="Done", command=lambda: close_window(window))
    button_go = tk.Button(window, text="Run", command=lambda: write_dict(window))

    label_title.grid   (row=0, column=1, sticky="nwse", padx=2, pady=2)
    label_name.grid    (row=1, column=0, sticky="e", padx=2, pady=2)
    entry_name.grid    (row=1, column=1, sticky="nwse", padx=2, pady=2)
    label_link.grid    (row=2, column=0, sticky="e", padx=2, pady=2)
    entry_link.grid    (row=2, column=1, sticky="nwse", padx=2, pady=2)
    label_xpath.grid   (row=3, column=0, sticky="e", padx=2, pady=2)
    entry_xpath.grid   (row=3, column=1, sticky="nwse", padx=2, pady=2)
    label_active.grid  (row=4, column=0, sticky="e", padx=2, pady=2)
    chbox_active.grid  (row=4, column=1, sticky="w", padx=2, pady=2)
    label_comment.grid (row=5, column=0, sticky="e", padx=2, pady=2)
    entry_comment.grid (row=5, column=1, sticky="w", padx=2, pady=2)

    window.grid_rowconfigure(6, minsize=20)  # Empty?

    botton_cancel.grid(row=7, column=0, sticky="w", padx=2, pady=2)  # Cancel Button
    button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2)  # Write Dict Button


def close_window(window):
    window.destroy()


def write_dict(window):

    i_dict = {}
    i_dict["name"] = entry_name.get()
    i_dict["link"] = entry_link.get()
    i_dict["xpath"] = entry_xpath.get()
    i_dict["active"] = box_var.get()
    i_dict["comment"] = entry_comment.get('1.0', tk.END)

    print(i_dict)
    pass


main_window()

I am trying to make a simple GUI do enter Data into a Dictionary. Most things i find online write the Tkinter straight into the .py, but i want to use a Function to Draw the Window, and another Function to do its stuff once a Button is pressed.

Shorted code:

def main_window():
    window = tk.Tk()
    build_window(window)
    window.mainloop()  
def build_window(window):
    entry_name = tk.Entry(window)
    button_go = tk.Button(window, text="Run", command=lambda: write_dict())
    button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2) 
def write_dict():
    i_dict = {}
    i_dict["name"] = entry_name.get()
main_window()

And i am getting AttributeError: module 'tkinter' has no attribute 'entry_name'. I tried various ways to get window into write_dict(), but i could never use .get() to read the values inside the Entry Box.

how would i do this?

Full code:

import tkinter as tk
import tkinter.scrolledtext as tkst
from PyQt5.QtWidgets import QApplication

d_list = []


def main_window():
    window = tk.Tk()
    window.title("New Entry")
    build_window(window)

    window.mainloop()  # Main Loop, nothing runs after here on Gui

def build_window(window):

    label_title = tk.Label(window, text="NEW ENTRY")
    label_name = tk.Label(window, text="Name:")
    entry_name = tk.Entry(window)
    label_link = tk.Label(window, text="Link:")
    entry_link = tk.Entry(window)
    label_xpath = tk.Label(window, text="XPath:")
    entry_xpath = tk.Entry(window)
    label_active = tk.Label(window, text="Active:")
    chbox_active = tk.Checkbutton(window, variable=1, text="Active")
    label_comment = tk.Label(window, text="Comment:")
    entry_comment = tkst.ScrolledText(window, width=40, height=4, font=("roboto", 8))
    botton_cancel = tk.Button(window, text="Done", command=lambda: close_window(window))
    button_go = tk.Button(window, text="Run", command=lambda: write_dict())

    label_title.grid   (row=0, column=1, sticky="nwse", padx=2, pady=2)
    label_name.grid    (row=1, column=0, sticky="e", padx=2, pady=2)
    entry_name.grid    (row=1, column=1, sticky="nwse", padx=2, pady=2)
    label_link.grid    (row=2, column=0, sticky="e", padx=2, pady=2)
    entry_link.grid    (row=2, column=1, sticky="nwse", padx=2, pady=2)
    label_xpath.grid   (row=3, column=0, sticky="e", padx=2, pady=2)
    entry_xpath.grid   (row=3, column=1, sticky="nwse", padx=2, pady=2)
    label_active.grid  (row=4, column=0, sticky="e", padx=2, pady=2)
    chbox_active.grid  (row=4, column=1, sticky="w", padx=2, pady=2)
    label_comment.grid (row=5, column=0, sticky="e", padx=2, pady=2)
    entry_comment.grid (row=5, column=1, sticky="w", padx=2, pady=2)

    window.grid_rowconfigure(6, minsize=20)  # Empty?

    botton_cancel.grid(row=7, column=0, sticky="w", padx=2, pady=2)  # Cancel Button
    button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2)  # Write Dict Button


def close_window(window):

    window.destroy()


def write_dict():
    global d_list
    i_dict = {}
    i_dict["name"] = entry_name.get()
    i_dict["link"] = entry_link.get()
    i_dict["xpath"] = entry_xpath.get()
    i_dict["active"] = chbox_active.get()
    i_dict["comment"] = entry_comment.get()

    print(i_dict)
    pass


main_window()

EDIT: The Full Errors are these 2, the first one is with the currently posted code, the second is with passing ´window´ into the button.

Traceback (most recent call last):
  File "C:\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 50, in <lambda>
    button_go = tk.Button(window, text="Run", command=lambda: write_dict())
  File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 78, in write_dict
    i_dict["name"] = entry_name.get()
NameError: name 'entry_name' is not defined
Traceback (most recent call last):
  File "C:\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 50, in <lambda>
    button_go = tk.Button(window, text="Run", command=lambda: write_dict(window))
  File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 78, in write_dict
    i_dict["name"] = window.entry_name.get()
  File "C:\Python\Python38\lib\tkinter\__init__.py", line 2345, in __getattr__
    return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'entry_name'
Beardlongo
  • 69
  • 5
  • 1
    Please update your question with the full error traceback. – quamrana May 27 '20 at 19:36
  • @quamrana done so, thought it doesnt tell me more then i wrote in the overpost. – Beardlongo May 27 '20 at 19:45
  • 1
    Well, it tells everyone else everything that is needed. We are not omniscient. Your first quote of the traceback did not even come from the posted code. – quamrana May 27 '20 at 19:52
  • Read up on [Tutorial - 9.2. Python Scopes and Namespaces](https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces) – stovfl May 27 '20 at 20:04

1 Answers1

1

Add global entry_name,entry_link,entry_xpath,chbox_active,entry_comment under the def build_window(window): It will fix Variable error.

And I fixed all of the issues Here is the Code:

import tkinter as tk
import tkinter.scrolledtext as tkst
#from PyQt5.QtWidgets import QApplication

d_list = []


def main_window():
    window = tk.Tk()
    window.title("New Entry")
    build_window(window)

    window.mainloop()  # Main Loop, nothing runs after here on Gui

def build_window(window):
    global entry_name,entry_link,entry_xpath,chbox_active,entry_comment,var
    var = tk.IntVar()
    label_title = tk.Label(window, text="NEW ENTRY")
    label_name = tk.Label(window, text="Name:")
    entry_name = tk.Entry(window)
    label_link = tk.Label(window, text="Link:")
    entry_link = tk.Entry(window)
    label_xpath = tk.Label(window, text="XPath:")
    entry_xpath = tk.Entry(window)
    label_active = tk.Label(window, text="Active:")
    chbox_active = tk.Checkbutton(window, variable=var, text="Active")
    label_comment = tk.Label(window, text="Comment:")
    entry_comment = tkst.ScrolledText(window, width=40, height=4, font=("roboto", 8))
    botton_cancel = tk.Button(window, text="Done", command=lambda: close_window(window))
    button_go = tk.Button(window, text="Run", command=lambda: write_dict())

    label_title.grid   (row=0, column=1, sticky="nwse", padx=2, pady=2)
    label_name.grid    (row=1, column=0, sticky="e", padx=2, pady=2)
    entry_name.grid    (row=1, column=1, sticky="nwse", padx=2, pady=2)
    label_link.grid    (row=2, column=0, sticky="e", padx=2, pady=2)
    entry_link.grid    (row=2, column=1, sticky="nwse", padx=2, pady=2)
    label_xpath.grid   (row=3, column=0, sticky="e", padx=2, pady=2)
    entry_xpath.grid   (row=3, column=1, sticky="nwse", padx=2, pady=2)
    label_active.grid  (row=4, column=0, sticky="e", padx=2, pady=2)
    chbox_active.grid  (row=4, column=1, sticky="w", padx=2, pady=2)
    label_comment.grid (row=5, column=0, sticky="e", padx=2, pady=2)
    entry_comment.grid (row=5, column=1, sticky="w", padx=2, pady=2)

    window.grid_rowconfigure(6, minsize=20)  # Empty?

    botton_cancel.grid(row=7, column=0, sticky="w", padx=2, pady=2)  # Cancel Button
    button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2)  # Write Dict Button


def close_window(window):

    window.destroy()


def write_dict():
    global d_list
    i_dict = {}
    v = ""
    i_dict["name"] = entry_name.get()
    i_dict["link"] = entry_link.get()
    i_dict["xpath"] = entry_xpath.get()
    i_dict["active"] = var.get()
    i_dict["comment"] = entry_comment.get('1.0', 'end-1c')

    print(i_dict)
    pass


main_window()

Now you can get checkbox status and comment box status too.

Osadhi Virochana
  • 1,294
  • 2
  • 11
  • 21
  • Thanks for that, it works! I Updated the post with running code. Though if it not too much to ask, why do i need to call the global vars in the build_window() and not in the button, that is called inside the build_window() function and uses them? – Beardlongo May 27 '20 at 20:07
  • Because that is the place assign values to variables. When we want to use that variable in other places, we have to define it as a global variable before assigning a value. – Osadhi Virochana May 27 '20 at 20:22