简体   繁体   中英

tkinter GUI writing to a text widget and replacing text

from tkinter import *
from tkinter import ttk

parent = Tk()

p = ttk.Panedwindow(parent, orient=HORIZONTAL)
p.pack(fill=BOTH, expand=1)

p1 = ttk.Panedwindow(parent, orient=HORIZONTAL)
p1.pack(fill=BOTH, expand=1)
f4 =ttk.Labelframe(p1, text='marks numbers histograms', width =400, height = 100)

p1.add(f4)

# declare and set variable(s)
marks_to_hist = StringVar()


# ROUTINE OPENS MARKS , TALLIES RANGES, DRAWS HISTOGRAM
def open_marks_numbers():

    N = int(marks_to_hist.get())
    N = N * 5
    marks = []
    for line in open('marks.txt').readlines():
       datafile = (line.strip().split('\t')[0].split(','))  
       for n in datafile:
          marks.append(int(n))
    marks=marks[:N]
    return marks

def open_numbers_for_draw(n):
    marks = open_marks_numbers()
    return marks[n-1::5]

def count_marks_range(numbers):
    marks_range_tally = [0] * 12
    for num in numbers[:]: 
        which_range=int(num//5)
        marks_range_tally[which_range] = marks_range_tally[which_range] + 1
    return marks_range_tally

def get_marks_tally():
    marks_range_tally = []
    draw_nums = [1,2,3,4,5] #or range(1,6)
    for n in draw_nums:
        numbers = open_numbers_for_draw(n)
        marks_range_tally.append(count_marks_range(numbers)) #create histogram, append to list
    return marks_range_tally

def write_histogram_marks():
    '''
    histogram format:
    1 - 4    **
    5 - 9    ***
    10 - 14  ******
    15 -19   **
    45 - 49  ****
    50       *

   '''
    import tkinter.filedialog
    histfilesaved =tkinter.filedialog.askopenfilename()
    histfile=open(histfilesaved,'w')
    marks_range_tally = get_marks_tally()
    # convert list to integers using list comprehension
    marks_count1 = [int(i) for i in marks_range_tally[0]]
    marks_count2 = [int(i) for i in marks_range_tally[1]]
    marks_count3 = [int(i) for i in marks_range_tally[2]]
    marks_count4 = [int(i) for i in marks_range_tally[3]]
    marks_count5 = [int(i) for i in marks_range_tally[4]]


    print(marks_count1 ,'\n', marks_count2, '\n' , marks_count3 , '\n', marks_count4 , '\n' , marks_count5)

    histfile.write('distribution of marks numbers \n')

    histfile.write('1-4:    ')
    histfile.write('*' * marks_count1[0])
    histfile.write(' ' * (22  -marks_count1[0]))
    histfile.write('1-4:    ')
    histfile.write('*' * marks_count2[0])
    histfile.write(' ' * (22  -marks_count2[0]))
    histfile.write('1-4:    ')
    histfile.write('*' * marks_count3[0])
    histfile.write(' ' * (22  -marks_count3[0]))
    histfile.write('1-4:    ')
    histfile.write('*' * marks_count4[0])
    histfile.write(' ' * (22  -marks_count4[0]))
    histfile.write('1-4:    ')
    histfile.write('*' * marks_count5[0])
    histfile.write('\n')

    histfile.write('5-9:    ')
    histfile.write('*' * marks_count1[1])
    histfile.write(' ' * (22 -marks_count1[1]))
    histfile.write('5-9:    ')
    histfile.write('*' * marks_count2[1])
    histfile.write(' ' * (22 -marks_count2[1]))
    histfile.write('5-9:    ')
    histfile.write('*' * marks_count3[1])
    histfile.write(' ' * (22 -marks_count3[1]))
    histfile.write('5-9:    ')
    histfile.write('*' * marks_count4[1])
    histfile.write(' ' * (22 -marks_count4[1]))
    histfile.write('5-9:    ')
    histfile.write('*' * marks_count5[1])
    histfile.write('\n')
    for i in range(2,10):
        low =  i * 5
        high = i * 5 + 4
        histfile.write(str(low) + '-' + str(high) + ':  ')
        histfile.write('*' * marks_count1[i])
        histfile.write(' ' * (22 -marks_count1[i]))
        histfile.write(str(low) + '-' + str(high) + ':  ')
        histfile.write('*' * marks_count2[i])
        histfile.write(' ' * (22 -marks_count2[i]))
        histfile.write(str(low) + '-' + str(high) + ':  ')
        histfile.write('*' * marks_count3[i])
        histfile.write(' ' * (22 -marks_count3[i]))
        histfile.write(str(low) + '-' + str(high) + ':  ')
        histfile.write('*' * marks_count4[i])
        histfile.write(' ' * (22 -marks_count4[i]))
        histfile.write(str(low) + '-' + str(high) + ':  ')
        histfile.write('*' * marks_count5[i])
        histfile.write('\n')
    histfile.write('50:     ')
    histfile.write('*' * marks_count1[-1])
    histfile.write(' ' * (22 -marks_count1[-1]))
    histfile.write('50:     ')
    histfile.write('*' * marks_count2[-1])
    histfile.write(' ' * (22 -marks_count2[-1]))
    histfile.write('50:     ')
    histfile.write('*' * marks_count3[-1])
    histfile.write(' ' * (22 -marks_count3[-1]))
    histfile.write('50:     ')
    histfile.write('*' * marks_count4[-1])
    histfile.write(' ' * (22 -marks_count4[-1]))
    histfile.write('50:     ')
    histfile.write('*' * marks_count5[-1])
    histfile.write('\n')
    histfile.close()
# ENDS marks NUMBERS FUNCTION

def evClear():
   num_draws.delete(0, END) ()# clears entry but causes error
   num_draws.focus() # places the cursor into the text box

def replace_histogram():

    data=open('histfile.txt','r')
    myData= data.read() # read the file to variable
    data.close()
    ViewHistogramWidget.insert(0.0,myData)
'''
BOTTOMFRAME (LEFT)
marks NUMBERS HISTOGRAMS
'''

from_lbl = Label(f4, text='how many records ? ', font='comic-sans-MS')
from_lbl.pack(side=TOP) 
num_draws =Entry(f4, textvariable=marks_to_hist, font='comic-sans-MS', width='2',insertbackground= 'red')
num_draws.pack(side=TOP) # enter number of records
enter_btn1 = Button(f4,text='draw new histogram', font='comic-sans-MS', command=replace_histogram)
enter_btn1.pack(side = BOTTOM, padx = 25)
clear_btn = Button(f4, text='clear', font='comic-sans-MS', command = evClear)
clear_btn.pack(side=BOTTOM, padx = 5)
ViewHistogramWidget= Text(f4,  width = 150) # set up a text widget as a root (window) child


with open('histfile.txt','r') as data:
   myText= data.read() # read the file to variable
   data.close() # close file handle

ViewHistogramWidget.insert(0.0,myText) # insert the file's text into the text widget

ViewHistogramWidget.pack(expand=1, fill=BOTH) # show the widget
mainloop()

marks data is in a comma delimited file with five marks per record eg

1,2,3,4,5
6,7,8,9,3

histfile is a simple textfile.

This 'routine' correctly displays the output of a histfile generated by write_histogram_marks() .

What I want it to be able to do is to generate a new histogram file based on a user-defined desired number of records (input into the variable marks_to_hist ), and write the new file to the text window (erasing the previous display). However using the replace_histogram simply rewrites the same file below the one already displayed. Also the evClear button I would like to use to clear both the entry field and the text window. At the moment it erases the entry but generates an error. I am sure that my histfile.write procedure is utterly clumsy and repetitive, but this is the only way for a 'newbie' like me could figure it out.

Have to say that I have had a lot of help from folk on stackOverflow to get this far. Help much appreciated

Use following classes and replace Text and Entry widgets, utilizing new setText and clear methods:

import Tkinter

class HistogramViewer(Tkinter.Text):
    def setText(self, text):
        self.clear()
        self.insert(Tkinter.END, text)

    def clear(self):
        self.delete("1.0", Tkinter.END)


class HistogramEntry(Tkinter.Entry):
    def setText(self, text):
        self.clear()
        self.insert(0, text)

    def clear(self):
        self.delete(0, Tkinter.END)

Improved based on notices from Bryan Oakley.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM