Python Forum

Full Version: Class with text widget method
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am quite new to Python and programming in general and just starting to work with Tkinter, so your patience and help is really appreciated.

I am trying to create a very simple Class that can display a string in a very rudimentary GUI by way of Tkinter and the 'text' widget. The goal is to be able to import this class, create an instance, and display text by calling a method that I built into this class.

I have been able to make it function, but not optimally. I have not been able to successfully create and pack the text widget with the constructor within my class ("__init__"). I have had to do it in actually within the method that I am using to insert content into the text widget.

This seems terribly inefficient. I would like to do all the set-up (frames, widgets, packing, etc) with the constructor and be able to reference them with functions.

Thanks in advance for any assistance.
Here is my script:

# Goal: create class and object/s to use in other apps

# Import module/s
from tkinter import *

# Create class
class Custom_Console:

	
	# Initialize root object
	def __init__(self, name):
	
		self.name = "new console"
		self.root = Tk()
		
		
		
	# Create widgets and call main loop in method (not optimal)
	def print_message(self, content):
	
		text_box = Text(self.root, bg="blue", fg="white")
		text_box.pack(side=LEFT)
		text_box.insert(END, content)
		self.root.mainloop()
	
		

# create object from 'Custom_Console' class
mycon = Custom_Console("main console")

# Declare variable for inserting text
content = "Here we go!!!"

# Call 'print_message' method to insert text into widget
mycon.print_message(content)
	
	
1. text_box need to be part of the class. don't make a new one each time method is called.
put in __init__
self.text_box = Text(self.root, bg = 'blue', fg = 'white')
self.text_box.pack(side=LEFT)
here another example
import tkinter as tk

# just inherit it to make custom tk.Text
class Custom_Console(tk.Text):
    def __init__(self, master):
        tk.Text.__init__(self, master, bg = 'blue', fg = 'white')
        self.pack(side = tk.LEFT)

    #custom methods
    def write(self, content):
        self.insert(tk.END, content)

    def writeln(self, content):
        self.insert(tk.END, content + '\n')

def main():
    root = tk.Tk()
    app = Custom_Console(root)
    app.insert(tk.END, "0 ")
    app.write("1 ")
    app.writeln("2")
    app.writeln("Here we go")
    app.mainloop()

if __name__ == '__main__':
    main()
if you start hard coding things within a class, you will be forever maintaining it, and thus overriding the
purpose of it in the first paste.

A Class is a container, just like a pan is a container.
you wouldn't want to have to buy a pan only for spegetti,
and another for oatmeal.
The pan remains the same, only the contents change.

The same is true about a well written class.
it should allow for certain inputs and methods that can (but don't have to) be used on
the object passed to the class. It's also capable of 'inheriting' all of the capabilities of
a parent class, and using the methods of the parent class without overhead.

It is perfectly ok to have a message server class, but the messages since they are volatile,
should be read from a file or database. Once you have that, the data can be changed at will
without ever having to change your class. Example:
test file for example: state.txt:
[attachment=286]
program getstates.py
import StateInfo as si

def main():
    sinfo = si.StateInfo('States.txt')
    print(sinfo.GetState('NY'))
    print(sinfo.GetState('CA'))
    print(sinfo.GetState('MT'))
    print(sinfo.GetState('ME'))

if __name__ == '__main__':
    main()
program StateInfo.py (the class):
class StateInfo:
    def __init__(self, statefile):
        self.statefile = statefile
        self.states = {}
        with open(self.statefile) as f:
            # skip header record
            next(f)
            # build dictionary
            for line in f:
                line = line.strip().split('|')
                alpha_state = line[1]
                self.states[alpha_state] = {}
                self.states[alpha_state]['Name'] = line[2]

    def GetState(self, state_abbr):
        return self.states[state_abbr]['Name']

if __name__ == '__main__':
    si = StateInfo('States.txt')
    print('State {} is {}'.format('MS', si.GetState('MS')))
results of running:
python getstates.py
Output:
New York California Montana Maine
Thank you, that is very helpful. I'll have to do some research into class inheritance tonight after work. I have a lot to learn.