Python Forum
[Tkinter] Class with text widget method
Thread Rating:
  • 1 Vote(s) - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Class with text widget method
#1
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)
	
	
Reply
#2
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()
99 percent of computer problems exists between chair and keyboard.
Reply
#3
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:

.txt   States.txt (Size: 1.51 KB / Downloads: 375)
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
Reply
#4
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.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  TKinter Widget Attribute and Method Quick Reference zunebuggy 3 850 Oct-15-2023, 05:49 PM
Last Post: zunebuggy
  [Tkinter] The Text in the Label widget Tkinter cuts off the Long text in the view malmustafa 4 4,858 Jun-26-2022, 06:26 PM
Last Post: menator01
  [Tkinter] Text widget inert mode on and off rfresh737 5 3,861 Apr-19-2021, 02:18 PM
Last Post: joe_momma
  Line numbers in Text widget rfresh737 3 5,405 Apr-15-2021, 12:30 PM
Last Post: rfresh737
  tkinter text widget word wrap position chrisdb 6 7,567 Mar-18-2021, 03:55 PM
Last Post: chrisdb
  method to add entries in multi columns entry frames in self widget sudeshna24 2 2,247 Feb-19-2021, 05:24 PM
Last Post: BashBedlam
  [PyQt] remove widget from other class issac_n 2 3,129 Aug-05-2020, 01:55 PM
Last Post: deanhystad
  [Tkinter] Get the last entry in my text widget Pedroski55 3 6,397 Jul-13-2020, 10:34 PM
Last Post: Pedroski55
  How to place global tk text widget in class or on canvas puje 1 2,328 Jul-04-2020, 09:25 AM
Last Post: deanhystad
  [PyQt] I get a name Name Error: when calling a method inside a class radoo 2 2,375 Jun-11-2020, 05:02 PM
Last Post: radoo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020