Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python/Tkinter How to update information in grid

I'm running Python 3.2.2 and writing some code to test sockets. For the ease of testing, I'm using Tkinter to add a GUI interface. What I have yet to figure out is how to update the information in the grid I'm using. I want to update "host2" and "port2" in the functions "change1" and "change3" in the following code:

import socket
from tkinter import *
import tkinter.simpledialog

root = Tk()
root.title("Server")
root.iconbitmap("etc.ico")
root.geometry("350x100+200+200")
frame = Frame(root)
host1 = Label(frame,text="Host: ").grid(row=0,column=0)
port1 = Label(frame,text="Port: ").grid(row=1,column=0)
HOST = 'localhost'
PORT = 11111
STATUS = 'EMPTY'
host2 = Label(frame,text=HOST,width=10).grid(row=0,column=1)
port2 = Label(frame,text=PORT,width=10).grid(row=1,column=1)
status1 = Label(root,text=STATUS)
status1.pack(side=RIGHT,padx=2,pady=2)

def change1():
    global HOST
    HOST= tkinter.simpledialog.askstring(title="Host",prompt="Enter the IP of the Host.")
    host2.grid_forget()
def change3():
    global PORT
    PORT= tkinter.simpledialog.askinteger(title="Port",prompt="Enter the Port of the IP.")
    port2.grid_forget()
def go1():
    global HOST
    global PORT
    home = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    home.bind((HOST, PORT))
    home.listen(1)
    conn, addr = home.accept()
    print (addr)
    while 1:
        data = conn.recv(1024)
        if not data: break
        global STATUS
        STATUS = data.decode('UTF-8')
        conn.send(bytes('Received "Hello World"','UTF-8'))
    conn.close()
    global status1
    status1.pack_forget()
    status1.pack(side=RIGHT,padx=2,pady=2)

change = Button(frame, text="Change Host", width=10,command=change1).grid(row=0,column=2)
change2 = Button(frame, text="Change Port", width=10,command=change3).grid(row=1,column=2)
go = Button(frame, text="GO!",command=go1,width =10).grid(row=2,column=2)
frame.pack(side=LEFT)

mainloop()

Any help on the matter would be much appreciated! Thanks!

like image 727
Ryan Scott Avatar asked Jan 12 '12 03:01

Ryan Scott


2 Answers

Your problems begin with this line:

host1 = Label(frame,text="Host: ").grid(row=0,column=0)

What you are doing is creating a label, using grid to place the label on the screen, then assigning host1 the result of the grid() command, which is the empty string. This makes it impossible to later refer to host1 to get a reference to the label.

Instead, you need to save a reference to the label. With that reference you can later change anything you want about the label:

host1 = Label(frame, text="Host: ")
host1.grid(row=0, column=0)
...
if (something_has_changed):
    host1.configure(text="Hello, world!")

Take it from someone with over a decade of experience with tk, it's better to separate your widget creation and layout. Your layout will almost certainly change over the course of development and it's much easier to do that when all your layout code is in one place. My layouts may change a lot but my working set of widgets rarely does, so I end up only having to change one block of code rather than dozens of individual lines interleaved with other code.

For example, my code generally looks roughly like this:

labell = tk.Label(...)
label2 = tk.Label(...)
entry1 = tk.Entry(...)

label1.grid(...)
label2.grid(...)
entry1.grid(...)

Of course, I use much better variable names.

like image 198
Bryan Oakley Avatar answered Sep 22 '22 11:09

Bryan Oakley


First, before going in depth with this problem. I want to highlight out a few things. In this line.

host2 = Label(frame,text=HOST,width=10).grid(row=0,column=1)

I want you to separate the gridding part from the declaration of the variable. Because it will create a No Type object that you cant work with. It will create many problems in the future that may take a lot of your time. If you have any variables structured like this that are not just going to be served as lines of text. Change the structure of that of that variable to the structure that I described above. Anyways, going back to what you where saying but in more depth is that to change the text of the Labels. What I would do if its going to be changed by function is in that function that you are wanting to change the text of the Label. Put in lines like this.

host2['text'] = 'Your New Text'
port2['text'] = 'Your New Text'

# or

host2.configure(text = 'Your New Text')
port2.configure(text = 'Your New Text')

This will change the text of your labels to the newly changed text or In other words replaces the text with the new text.

like image 42
Darren Samora Avatar answered Sep 26 '22 11:09

Darren Samora