如何将所有分类结果打印到 GUI 上的文本小部件?

Posted

技术标签:

【中文标题】如何将所有分类结果打印到 GUI 上的文本小部件?【英文标题】:How can I print all the classification results to the Text widget on my GUI? 【发布时间】:2021-10-31 03:13:11 【问题描述】:

我有一个图形用户界面,可以将图像分类为正确或错误。如何在文本小部件中打印所有结果,以便在单击用户控制按钮后将所有结果打印出来?当我单击该按钮时,我希望在小部件中打印所有答案。但是,它只打印最后一个结果

这是我的代码

from tkinter import *
from PIL import Image,ImageTk
from tkinter import filedialog
from PIL import Image, ImageTk
import os
import cv2
import numpy as np
import time
class application(Tk):
    def __init__(self,parent):
        Tk.__init__(self,parent)
        self.parent = parent
        self.minsize(width=300,height=500)
        self.initialize()
        
    def initialize(self):
        self.grid_columnconfigure(0,weight=1)
        self.grid_columnconfigure(1,weight=1)
        self.grid_columnconfigure(2,weight=1)
        
        #Button widgets
        ###########################################################################################
        #self.button1 = Button(self,text='Image Selector',bg= 'blue',width=15,height=2,command=self.browseFiles)
        #self.button1.grid(column=0,row=1,sticky='W',pady=5)
        
        self.button2 = Button(self,text='User control',bg= 'blue',width=15,height=2,command=self.Image_Classification)
        self.button2.grid(column=0,row=1,sticky='W',pady=5,padx=150)
        
        self.button3 = Button(self,text='Exit',bg= 'blue',width=10,height=2,command=self.destroy)
        self.button3.grid(column=1,row=5,sticky='W',pady=5)
        
        #self.button4 = Button(self,text='Method 2',width=10,height=2)
        #self.button4.grid(column=0,row=2,sticky='W',pady=5)
        
        #Text widget for inserting result
        ############################################################################################
        self.text1 = Text(self,height=2,width=20,state=NORMAL)
        self.text1.grid(column=2,row=1,sticky='E',padx=5)
        #self.text1.configure(bg='cyan')
        
        #self.canvas2 = Canvas(self,height=10,width=20,state=NORMAL)
        #self.canvas2.grid(column=2,row=2,sticky='E',padx=5)
        
        self.text3 = Text(self,height=2,width=20,state=NORMAL)
        self.text3.grid(column=2,row=3,sticky='E',padx=5)
        
        self.canvas = Canvas(self,width=230,height=180,state=NORMAL)
        self.canvas.grid(column=0,row=4,sticky='W',padx=100,pady=10)
        #self.canvas.configure(bg='green')
        
        #Label widget
        ############################################################################################
        self.label1 = Label(self,text="Mode", bg = 'red', width=10,height=2,anchor="center")
        self.label1.grid(column=0,row=0,sticky='W',padx=120)
        
        self.label2 = Label(self,text="Inspection",bg = 'red',width=20,height=2,anchor="center")
        self.label2.grid(column=2,row=0,sticky='E',padx=50)
        
        self.label3 = Label(self,text="Image",bg = 'red',width=10,height=2,anchor="center")
        self.label3.grid(column=0,row=3,sticky='W',padx=120)
        
        self.label4 = Label(self,text="Classification",bg = 'red',width=10,height=2,anchor="center")
        self.label4.grid(column=1,row=1,sticky='E',pady=10)
        
        #self.label5 = Label(self,text="Result 2(Black Spot)",width=30,height=2,anchor="e")
        #self.label5.grid(column=1,row=2,sticky='E',pady=10)
        
        self.label6 = Label(self,text="Time",bg = 'red',width=10,height=2,anchor="center")
        self.label6.grid(column=1,row=3,sticky='E',pady=10)
    

        
    '''def browseFiles(self):
        self.filename = filedialog.askopenfilename(initialdir = '/',title = "Select a File",
                                                   filetypes = [("image",".jpeg"),("image",".png"),("image",".jpg")])  
        start=time.time()
        self.imageFile = ImageTk.PhotoImage(file=self.filename)
        self.canvas.create_image(50,10,image=self.imageFile,anchor=NW)
        self.img = cv2.imread(self.filename)
        self.hist = cv2.calcHist([self.img], [0], None, [256], [0,256])
        self.mean_px = cv2.mean(self.img)  
        self.max_nums = max(self.hist); self.max_num = str(self.max_nums)
        self.max_num_px= np.where(self.hist==self.max_nums)[0]+1; self.max_num_px = str(self.max_num_px)  
        self.min_nums = min(self.hist); self.min_num = str(self.min_nums)
        self.min_num_px= np.where(self.hist==self.min_nums)[0]+1; self.min_num_px = str(self.min_num_px)  
        self.hist_2_num = round((self.max_nums*(2/5))[0])
        self.hist_2_min_num = self.hist[self.hist>=self.hist_2_num][0]
        self.hist_2_max_num = self.hist[self.hist>=self.hist_2_num][len(self.hist[self.hist>=self.hist_2_num])-1]
        self.hist_2_min_val = np.where(self.hist==self.hist_2_min_num)[0][0]+1
        self.hist_2_max_val = max(np.where(self.hist==self.hist[self.hist>=self.hist_2_num][len(self.hist[self.hist>=self.hist_2_num])-1])[0])
        self.hist_2_diff = self.hist_2_max_val - self.hist_2_min_val
        self.results = []
        if self.hist_2_diff>50:
            self.results.append('good')
        else:
            self.results.append('bad')
        for choices in self.results:
            self.text1 = Text(self,height=2,width=20,state=NORMAL)
            self.text1.insert(END,str(choices))
            self.text1.grid(column=2,row=1,sticky='E',padx=5)
        end=time.time()
        Time_elapsed=':.3fs'.format(end-start)
        text3 = Text(self,height=2,width=20,state=NORMAL)
        text3.insert(END,str(Time_elapsed))
        text3.grid(column=2,row=3,sticky='E',padx=5)'''
    
    def Image_Classification(self):
        start=time.time()
        for self.i in range(1,31):
            for self.j in range(1,11): 
                self.filename = 'Path/Folder_'+str(self.i)+'/'+str(self.j)+'.jpg'
                self.img = cv2.imread(self.filename)
                self.hist = cv2.calcHist([self.img], [0], None, [256], [0,256])
                self.mean_px = cv2.mean(self.img)  
                self.max_nums = max(self.hist); self.max_num = str(self.max_nums)
                self.max_num_px= np.where(self.hist==self.max_nums)[0]+1; self.max_num_px = str(self.max_num_px)  
                self.min_nums = min(self.hist); self.min_num = str(self.min_nums)
                self.min_num_px= np.where(self.hist==self.min_nums)[0]+1; self.min_num_px = str(self.min_num_px)  
                self.hist_2_num = round((self.max_nums*(2/5))[0])
                self.hist_2_min_num = self.hist[self.hist>=self.hist_2_num][0]
                self.hist_2_max_num = self.hist[self.hist>=self.hist_2_num][len(self.hist[self.hist>=self.hist_2_num])-1]
                self.hist_2_min_val = np.where(self.hist==self.hist_2_min_num)[0][0]+1
                self.hist_2_max_val = max(np.where(self.hist==self.hist[self.hist>=self.hist_2_num][len(self.hist[self.hist>=self.hist_2_num])-1])[0])
                self.hist_2_diff = self.hist_2_max_val - self.hist_2_min_val
                self.results = []
                
                if self.hist_2_diff>50:
                    self.results.append(': good'.format(self.j))
                    print(': good'.format(self.j))
                else:
                    self.results.append(': bad'.format(self.j))
                    print(': bad'.format(self.j))
                for choices in self.results:
                    self.text1 = Text(self,height=2,width=20,state=NORMAL)
                    self.text1.insert(END,str(choices))
                    self.text1.grid(column=2,row=1,sticky='E',padx=5)
                    #self.text1.tag_config(background='blue')
                self.j+=1
                end=time.time()
                Time_elapsed=':.3fs'.format(end-start)
                text3 = Text(self,height=2,width=20,state=NORMAL)
                text3.insert(END,str(Time_elapsed))
                text3.grid(column=2,row=3,sticky='E',padx=5)
        
if __name__ == "__main__":
    app = application(None)
    #font.nametofont('TkDefaultFont').configure(size=10)
    app['bg']='Cyan'
    app.title("Trial")
    app.mainloop()

我的结果

预期结果

测试图像

【问题讨论】:

获得该结果的原因是因为您在循环中创建 Text 小部件,然后插入文本。相反,您应该将所有 Text 小部件创建移到循环之外,可能位于 initialize 方法中的某个位置,并且只保留循环中的插入。 这就是我卡住的地方!当我在循环中删除它时,我在循环之外创建了我也看不到结果! 您是否在initialize 方法中创建了文本小部件? 【参考方案1】:

您不应创建新的Text 小部件来存储每次迭代中的结果。由于您已经创建了那些 Text 小部件来显示结果和在 initialize() 中经过的时间,您可以在 for 循环之后将结果插入到这些小部件中:

def Image_Classification(self):
    self.results = []
    start = time.time()

    for self.i in range(1, 31):
        for self.j in range(1, 11):
            self.filename = 'Path/Folder_'+str(self.i)+'/'+str(self.j)+'.jpg'
            self.img = cv2.imread(self.filename)
            self.hist = cv2.calcHist([self.img], [0], None, [256], [0,256])
            self.mean_px = cv2.mean(self.img)
            self.max_nums = max(self.hist); self.max_num = str(self.max_nums)
            self.max_num_px = np.where(self.hist==self.max_nums)[0]+1; self.max_num_px = str(self.max_num_px)
            self.min_nums = min(self.hist); self.min_num = str(self.min_nums)
            self.min_num_px = np.where(self.hist==self.min_nums)[0]+1; self.min_num_px = str(self.min_num_px)
            self.hist_2_num = round((self.max_nums*(2/5))[0])
            self.hist_2_min_num = self.hist[self.hist>=self.hist_2_num][0]
            self.hist_2_max_num = self.hist[self.hist>=self.hist_2_num][len(self.hist[self.hist>=self.hist_2_num])-1]
            self.hist_2_min_val = np.where(self.hist==self.hist_2_min_num)[0][0]+1
            self.hist_2_max_val = max(np.where(self.hist==self.hist[self.hist>=self.hist_2_num][len(self.hist[self.hist>=self.hist_2_num])-1])[0])
            self.hist_2_diff = self.hist_2_max_val - self.hist_2_min_val

            result = 'good' if self.hist_2_diff > 50 else 'bad'
            self.results.append(f'self.i.self.j: result')

    end = time.time()
    time_elapsed = f'end-start:.3fs'
    self.text3.delete('1.0', END)
    self.text3.insert(END, time_elapsed)

    self.text1.delete('1.0', END)
    for result in self.results:
        self.text1.insert(END, f'result\n')

更新:为self.text1添加滚动条:

def initialize(self):
    ...
    self.text1 = Text(self, height=2, width=20, state=NORMAL)
    self.text1.grid(column=2, row=1, sticky='nse', padx=5)

    self.scrollbar1 = Scrollbar(self, orient=VERTICAL, command=self.text1.yview)
    self.scrollbar1.grid(column=3, row=1, sticky='ns')
    self.text1.config(yscrollcommand=self.scrollbar1.set)
    ...

【讨论】:

非常感谢您的帮助,有没有办法让文本小部件可滚动?请给点建议 @KimwagaMakono 您可以使用鼠标滚轮滚动文本小部件的内容。已更新答案以包含 self.text1 的滚动条。 非常感谢我已经更新了它,它显示但它处于非活动状态@acw1668 @KimwagaMakono 滚动条最初应该是非活动的,因为文本框中没有内容。在单击User control 并将结果附加到文本框后,滚动条应该会变为活动状态。

以上是关于如何将所有分类结果打印到 GUI 上的文本小部件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将回车键绑定到 tkinter 中的函数?

如何将捕获的输入从 tkinter 条目小部件写入 json 文件

从 Qt 中的文本文件填充表格小部件

如何使用按钮小部件执行外部脚本?

如何使用 tkinter 中的按钮设置“Entry”小部件的文本/值/内容

如何从Tkinter,Python中的Text小部件中移除焦点