用Tkinter实现首个GUI

感觉tutorialspoint看的东西还多一点,其他的只能自己尝试。


第一步 白板代码

先把窗口和组件画出来,再慢慢添加属性和方法

···

import tkinter as tk 

if __name__ == "__main__":  
root = tk.Tk()  
root.columnconfigure(0, weight=1)  
root.rowconfigure(0, weight=1)  
root.geometry('600x360')  #设置了主窗口的初始大小960x540 800x450 640x360  

outputText = tk.Text(root)
outputText.grid(row=0,column=0,columnspan=7)
outputText.config(state=DISABLED)

inputLabel= tk.Label(root,text='请输入需要查询天气的城市或者指令:')
inputLabel.grid(row=1,column=0,columnspan=2)

inputEntry= tk.Entry(root)
inputEntry.grid(row=1,column=2)
inputEntry.focus_set()

queryButton= tk.Button(root,text='查询', command=queryAction)
queryButton.grid(row=1,column=3)

historyButton= tk.Button(root,text='History', command=printHelpInfo)
historyButton.grid(row=1,column=4)

quitButton= tk.Button(root,text='退出',command=quitApp)
quitButton.grid(row=1,column=5)


root.mainloop()

···

程序运行窗口:


    from Tkinter import *

    master = Tk()
    Label(master, text="First").grid(row=0)
    Label(master, text="Second").grid(row=1)

    e1 = Entry(master)
    e2 = Entry(master)

    e1.grid(row=0, column=1)
    e2.grid(row=1, column=1)

    mainloop()

四个控件直接就像Excel表格一样排列,代码简单,界面整齐。


第二步 窗口正常工作

这一步复用了CH1的代码,很快就可以输出信息了。

踩过的坑:

  • IndentationError: unindent does not match any outer indentation level

这个坑真是郁闷啊,是没有对齐。代码看了好多次都没什么问题,结果发现不同的编辑器对缩进是不一样的!

记得要将Tab设为4个空格!记得要将Tab设为4个空格!记得要将Tab设为4个空格!


第三步 封装

将代码封装为一个窗口Class,以后其他模块可以直接调用这个窗口。

踩过的坑:

  • class内所有的属性、方法和变量,前面都要加上self.,否则会提示对应的属性、方法、变量没有定义。

    第一次报错时,阅读后没有发现明显错误,一运行时就提示没有找到定义。仔细想了一下,没有指定self的话,确实没有找到外部有定义该方法和函数,加入self.后解决。

  • TypeError: func() takes 0 positional arguments but 1 was given 方法和函数中,参数表中没有加入(self)。如果没有加的话,会有报错,提示方法和函数没有参数,但传递了一个,其实这个就是实例self。

    这里有一篇文章写得很详细,可以以后再读:一篇文章让你彻底搞清楚Python中self的含义

踩坑之后,窗口终于出现鸟:

下一步再进行界面优化,以及尝试一下其他的GUI库。


附上程序代码:

gui.py:

import tkinter as tk
import datetime

class WeatherQueryFrame(tk.Frame):

    city_weather={}
    queryHistory=[]

    def __init__(self, master=None):
        super().__init__(master)
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        self.outputText = tk.Text(self)
        #outputText.config(state=DISABLED)
        self.outputText.grid(row=0,column=0,columnspan=7)
        #self.outputText.insert(tk.END,city_weather['北京'])

        self.inputLabel= tk.Label(self,text='请输入需要查询天气的城市或者指令:')
        self.inputLabel.grid(row=1,column=0,columnspan=2)

        self.inputEntry= tk.Entry(self)
        self.inputEntry.grid(row=1,column=2)
        self.inputEntry.bind('<Return>',self.getEnter)
        self.inputEntry.insert(0,'广州')
        self.inputEntry.focus_set()

        self.queryButton= tk.Button(self,text='查询', command=self.queryAction)
        self.queryButton.grid(row=1,column=3)

        self.helpButton= tk.Button(self,text='帮助', command=self.printHelpInfo)
        self.helpButton.grid(row=1,column=4)

        self.historyButton= tk.Button(self,text='History', command=self.getHistory)
        self.historyButton.grid(row=1,column=5)

        self.quitButton= tk.Button(self,text='退出',command=self.quitApp)
        self.quitButton.grid(row=1,column=6)

        #初始化时读入城市天气结果
        with open ('weather_info.txt', 'r', encoding='utf-8') as f:
            for lines in f.readlines():
                line=lines.strip().split(',')
                self.city_weather[line[0]] = line[1]

    def getEnter(self,event):
        self.queryAction()

    def printHelpInfo(self):
        '''函数功能:打印帮助信息'''
        helpstr='''
    - 输入城市名,获取该城市的天气情况;
    - 输入 ?/help,获取本帮助信息;
    - 输入 h/history,获取历史查询信息;
    - 输入 q/quit,退出天气查询系统。\n'''

        #console打印输出
        print (helpstr)
        #窗口显示结果
        self.outputText.insert(tk.END,helpstr+'\n')

    def printErrorInfo(self):
        '''函数功能:打印错误信息'''
        printstr='''你输入的城市名称不存在,或者指令错误,请重新输入。
    - 如果不清楚指令,可以输入?或者help, 或点击"帮助"按钮,获取帮助。
    \n'''
        print(printstr)
        self.outputText.insert(tk.END,printstr)

    def getHistory(self):
        '''函数功能:打印历史查询信息,输出查询序号、时间和结果
        调用格式:getHistory(history)
        需要输入历史查询记录'''
        history=self.queryHistory
        if history:
            print ()
            print ('你查询过以下城市的天气情况:')
            self.outputText.insert(tk.END,'\n你查询过以下城市的天气情况:\n')
            for i in range(history.__len__()):
                printstr=str(i+1)+'   '+history[i]
                print (printstr)
                #窗口显示结果
                self.outputText.insert(tk.END,printstr)
        else:
            print ('并无查询历史记录')
            self.outputText.insert(tk.END,'并无查询历史记录\n')

    def printWeatherInfo(self,city,history):
        print (city, self.city_weather[city])
        self.outputText.insert(tk.END,city  + ' 的天气情况为:' + self.city_weather[city] + '\n')
        #获得当前时间
        now = datetime.datetime.now()
        #转换为指定的格式:
        dt = now.strftime("%Y-%m-%d %H:%M:%S")
        historystr=dt + '  ' + city + ' 的天气情况为:' + self.city_weather[city] + '\n'
        history.append(historystr)
        return history

    def queryAction(self):
        user_input=self.inputEntry.get().lower()
        if user_input=="help"  or user_input=="?":
            self.printHelpInfo()
            self.inputEntry.delete(0, tk.END)

        elif user_input=="h" or user_input=="history":
            self.getHistory()
            self.inputEntry.delete(0, tk.END)

        elif user_input in self.city_weather:
            self.queryHistory=self.printWeatherInfo(user_input,self.queryHistory)
            self.inputEntry.delete(0, tk.END)

        elif user_input=="q" or user_input=="quit":
            self.quitApp()

        else:
            errorstr='你刚刚输入的 "'+user_input+ '" 有误:\n'
            print (errorstr)
            self.outputText.insert(tk.END,errorstr)
            self.printErrorInfo()
            self.inputEntry.delete(0, tk.END)

    def quitApp(self):
        self.getHistory()
        print ('欢迎再次使用天气查询窗口,再见!')
        self.master.destroy()



if __name__ == "__main__":
    root = tk.Tk()
    root.wm_title('天气查询窗口')
    root.geometry('600x360')

    main_frame=WeatherQueryFrame(root)
    main_frame.mainloop()

results matching ""

    No results matching ""