tkinter GUI写入文本控件并替换文本

7 投票
1 回答
22873 浏览
提问于 2025-04-17 13:14
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()

这些分数数据保存在一个用逗号分隔的文件里,每条记录有五个分数,比如说:

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

histfile是一个简单的文本文件。

这个“程序”可以正确显示由write_histogram_marks()生成的histfile的输出。

我希望它能根据用户定义的记录数量(输入到变量marks_to_hist中)生成一个新的直方图文件,并把新文件写到文本窗口里(覆盖之前的显示)。但是使用replace_histogram时,它只是把同一个文件重新写在已经显示的文件下面。此外,我希望使用evClear按钮来清空输入框和文本窗口。目前它只能清空输入框,但会产生一个错误。我知道我的histfile.write过程非常笨拙和重复,但这对像我这样的“新手”来说是唯一能想到的办法。

不得不说,我在stackOverflow上得到了很多人的帮助,才能走到这一步,非常感谢大家。

1 个回答

9

使用以下类,替换掉文本和输入框小部件,利用新的 setText 和 clear 方法:

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)

这个改进是根据 Bryan Oakley 的建议做的。

撰写回答