分享

用Python创建你第一个GIS程序[6]:python2.7 Tkinter 界面美化最终方案

 GIS荟 2021-09-19
前言:有的人不喜欢 Tkinter 的一个重要原因就是其界面太丑,而我也偶尔觉得。在前后一年的时间中,针对 Tkinter 的美化尝试做了无数次,最终我选择了以下这种方案...


图形化按钮

使用图形化的按钮比如这个 这个来替代原来的丑陋按钮。

# -*- coding:utf-8 -*-

import Tkinter as tk
import tkFileDialog
from multiprocessing import Process
import giscode


class MyGUI(object):
   def __init__(self):
       self.root = tk.Tk()
       self.root.geometry("450x600+800+200")
       self.root.title("GIS") #设置程序名称
       self.var = tk.StringVar()

       #<<注释1>> 获取图像
       self.img1 = tk.PhotoImage(file="icon/shp2.gif")
       self.img2 = tk.PhotoImage(file="icon/ok2.gif")
       
       # run function
       self.create_widget()
       self.create_run_button()
       self.root.mainloop() # 执行循环

   def create_widget(self):
       self.frame1 = tk.Frame(self.root, relief="raised", bd=3)
       self.frame1.pack(fill="x")
       self.entry = tk.Entry(self.frame1)
       self.entry.config(textvariable=self.var)
       self.entry.pack(
           side="left",expand=True, fill="x", pady=8, padx=10
      )
       self.but = tk.Button(
           self.frame1, text=u"输入线要素", relief="flat", width=30
      ) #<<注释2>> 设置按钮的边框样式
       self.but.config(command=self.open_dialog)
       self.but.config(image=self.img1) #<<注释3>>
       self.but.pack(side="right", pady=8)
   
   def open_dialog(self):
       varrr = tkFileDialog.askopenfilename()
       self.var.set(varrr)
       
   def create_run_button(self):
       # 生成下方的“运行”按钮
       self.bottom_frame = tk.Frame(self.root,relief="raised",bd=3)
       self.bottom_frame.pack(side="bottom",fill="x",anchor="s")
       self.ok_button = tk.Button(
           self.bottom_frame,text=u"运行", relief="flat", width=30
      ) #<<注释4>>
       self.ok_button.pack(side="right", pady=8)
       self.ok_button.config(image=self.img2)#<<注释5>>
       self.ok_button.config(command=self.run_multiprocessing)
   
   # def run(self):
   #     giscode.main(self.var.get())
   
   def run_multiprocessing(self):
       p = Process(target=giscode.main,
                   args=(self.var.get(),)
                  )
       p.start()
       print "PID:",p.pid
       
       
if __name__ == '__main__':
   MyGUI()


<<注释1>>:
获取图像。Tkinter 中的 PhotoImage 类用于获取图像。
由于 Python2.7 中的 Tkinter 只支持 GIF 和PPM/PGM 格式,不支持 PNG 格式,所以最好不要选择带有阴影的图标,GIF 是不支持阴影效果的。
不然的话阴影就会变成这样 和这样
原本外圈的阴影就会变成这种黑点点。

如果想要 Tkinter 支持 PNG 格式的话有两种方法,毕竟 PNG 格式的表现能力比 GIF 高不少。
  • 使用 PIL 包。缺点是引入的第三方包。

  • 升级到 Python3。但是 Python 无法使用 ArcPy。


<<注释2>> & <<注释4>> :
设置按钮的边框样式。参数 relief 控制边框的样式。一共有5种样式,分别是 flat、raised、sunken、groove、ridge。


现在流行扁平风格嘛,就选择了 flat 样式 。
<<注释3>> & <<注释5>> :
将按钮的图像设置为选中的图像。
设置了图像,先前设置的按钮的文字就不会显示了。

旧界面

新界面

Note: 源代码、icon图标和资料下载见最后。


使用ThemedTk设置主题

使用 ttkthemes 更改主题。
ttkthemes 官方文档:
https://ttkthemes./en/latest/themes.html
GitHub:
https://github.com/TkinterEP/ttkthemes

版本1

# -*- coding:utf-8 -*-

import Tkinter as tk
import tkFileDialog
from multiprocessing import Process
from ttkthemes import ThemedTk #<<注释1>>
import ttk #<<注释2>>
import giscode


class MyGUI(object):
   def __init__(self):
       # self.root = tk.Tk()
       self.root = ThemedTk(theme="arc") #<<注释3>>
       self.root.geometry("450x600+800+200")
       self.root.title("GIS") #设置程序名称
       self.var = tk.StringVar()

       self.img1 = tk.PhotoImage(file="icon/shp2.gif")
       self.img2 = tk.PhotoImage(file="icon/ok2.gif")
       
       # run function
       self.create_widget()
       self.create_run_button()
       self.root.mainloop() # 执行循环

   def create_widget(self):
       self.frame1 = ttk.Frame(self.root)
       self.frame1.pack(fill="x")
       self.entry = ttk.Entry(self.frame1) #<<注释4>>
       self.entry.config(textvariable=self.var)
       self.entry.pack(
           side="left",expand=True, fill="x", pady=8, padx=10
      )
       # self.but = tk.Button(self.frame1, relief="flat")
       self.but = ttk.Button(self.frame1)
       self.but.config(command=self.open_dialog)
       self.but.config(image=self.img1)
       self.but.pack(side="right", pady=8, padx=6)
   
   def open_dialog(self):
       varrr = tkFileDialog.askopenfilename()
       self.var.set(varrr)
       
   def create_run_button(self):
       # 生成下方的“运行”按钮
       self.bottom_frame = ttk.Frame(self.root)
       self.bottom_frame.pack(side="bottom",fill="x",anchor="s")
       # self.ok_button = tk.Button(self.bottom_frame, relief="flat")
       self.ok_button = ttk.Button(self.bottom_frame)
       self.ok_button.pack(side="right", pady=8, padx=6)
       self.ok_button.config(image=self.img2)
       self.ok_button.config(command=self.run_multiprocessing)
   
   # def run(self):
   #     giscode.main(self.var.get())
   
   def run_multiprocessing(self):
       p = Process(target=giscode.main,
                   args=(self.var.get(),)
                  )
       p.start()
       print "PID:",p.pid
       
       
if __name__ == '__main__':
   MyGUI()


<<注释1>>&<<注释2>>:
ttkthemes 模块要和 ttk 模块配合使用。
因为 ttkthemes 只能修改使用 ttk 制作的组件。

<<注释3>>:
支持 python2.7 的最新 ttkthemes 版本为2.4.0。经测试,该版本支持 aquativo、arc、black、blue、clearlooks、elegance、equilux等主题。
最喜欢的主题还是 arc 。


<<注释4>>:
由于ttkthemes 只能修改使用 ttk 制作的组件的样式,所以需要将 tk.Entry 替换为 ttk.Entry 即可。

最终效果如下:


版本2

由于ttk.Button 修改按钮边框比较困难。
你可以保留 tk.Button,relief 设置为 flat,其代码和效果如下:

# -*- coding:utf-8 -*-

import Tkinter as tk
import tkFileDialog
from multiprocessing import Process
from ttkthemes import ThemedTk #<<注释1>>
import ttk #<<注释2>>
import giscode


class MyGUI(object):
   def __init__(self):
       # self.root = tk.Tk()
       self.root = ThemedTk(theme="arc") #<<注释3>>
       self.root.geometry("450x600+800+200")
       self.root.title("GIS") #设置程序名称
       self.var = tk.StringVar()

       self.img1 = tk.PhotoImage(file="icon/shp2.gif")
       self.img2 = tk.PhotoImage(file="icon/ok2.gif")
       
       # run function
       self.create_widget()
       self.create_run_button()
       self.root.mainloop() # 执行循环

   def create_widget(self):
       self.frame1 = ttk.Frame(self.root)
       self.frame1.pack(fill="x")
       self.entry = ttk.Entry(self.frame1) #<<注释4>>
       self.entry.config(textvariable=self.var)
       self.entry.pack(
           side="left",expand=True, fill="x", pady=8, padx=10
      )
       self.but = tk.Button(self.frame1, relief="flat")
       # self.but = ttk.Button(self.frame1)
       self.but.config(command=self.open_dialog)
       self.but.config(image=self.img1)
       self.but.pack(side="right", pady=8, padx=6)
   
   def open_dialog(self):
       varrr = tkFileDialog.askopenfilename()
       self.var.set(varrr)
       
   def create_run_button(self):
       # 生成下方的“运行”按钮
       self.bottom_frame = ttk.Frame(self.root)
       self.bottom_frame.pack(side="bottom",fill="x",anchor="s")
       self.ok_button = tk.Button(self.bottom_frame, relief="flat")
       # self.ok_button = ttk.Button(self.bottom_frame)
       self.ok_button.pack(side="right", pady=8, padx=6)
       self.ok_button.config(image=self.img2)
       self.ok_button.config(command=self.run_multiprocessing)
   
   # def run(self):
   #     giscode.main(self.var.get())
   
   def run_multiprocessing(self):
       p = Process(target=giscode.main,
                   args=(self.var.get(),)
                  )
       p.start()
       print "PID:",p.pid
       
       
if __name__ == '__main__':
   MyGUI()



两者在按钮的边框有一些不同之处。


结束语

以上,就是我一直在使用的美化方案,使用图片来替代按钮,然后使用 ttktkemes 模块做进一步的处理。
美化之后的 Tkinter 界面是非常漂亮的

《用Python创建你第一个GIS程序》该系列所有教程资料下载:

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多