开源一个个人博客后台

自己想搞个个人博客,用GitHub Pages来做,但不怎么会HTML和JS,CSS一点儿也不会,只能通过本地的博客后台来实现发博客。

开源一下,底下是代码

代码

import requests
import tkinter as tk
import time
from tkinter import ttk  # Normal Tkinter.* widgets are not themed!
import markdown

# 读取文件
def open_file(file_path):
    with open(file_path, 'wb+') as f:
        return f.read()

def writeToken():
    token=token_enter.get()
    user=user_enter.get()
    email=email_enter.get()
    with open("./settings/token.set",'w') as f:
        f.write(token)
    with open("./settings/user.set",'w') as f:
        f.write(user)
    with open("./settings/email.set",'w') as f:
        f.write(email)
    token_win.destroy()

#读取设置
with open("./settings/token.set",'r') as f:
    token=f.read()
with open("./settings/user.set",'r') as f:
    user=f.read()
with open("./settings/email.set",'r') as f:
    email=f.read()
with open("./settings/post_formwork.set",'r') as f:
    post_formwork=f.read()


def post(content,name):
    global user
    upload_file(content,name+".html",user,user+".github.io","post/")

def md_post(content,name,title):
    html_cont=markdown.Markdown(content)
    html=post_formwork.format(title=title,name=name,content=content)
    post(html,name)

# 将文件转换为base64编码,上传文件必须将文件以base64格式上传
def file_base64(data):
    data_b64 = base64.b64encode(data).decode('utf-8')
    return data_b64


# 上传文件
def upload_file(file_data,file_name,user,repo,path=""):
    global token,email
    url = "https://api.github.com/repos/"+user+"/"+repo+"/contents/"+path+file_name  # 用户名、库名、路径
    headers = {"Authorization": "token " + token}
    content = file_base64(file_data)
    data = {
        "message": "message",
        "committer": {
            "name": user,
            "email": email
        },
        "content": file_data
    }
    data = json.dumps(data)
    req = requests.put(url=url, data=data, headers=headers)
    req.encoding = "utf-8"
    re_data = json.loads(req.text)
    print(re_data)
    print(re_data['content']['sha'])
    print("https://cdn.jsdelivr.net/gh/[user]/[repo]/[path]"+file_name)

def md():
    md_win=tk.Tk()
    md_win.title('MarkDown编辑器')
    tk.Label(md_win,text='博客名称').pack()
    name_enter=ttk.Entry(md_win)
    name_enter.pack(fill=tk.X)
    tk.Label(md_win,text='博客标题').pack()
    title_enter=ttk.Entry(md_win)
    title_enter.pack(fill=tk.X)
    tk.Label(md_win,text='博客内容').pack()
    scroll = tk.Scrollbar(md_win)
    md_enter=tk.Text(md_win)
    # 将滚动条填充
    scroll.pack(side=tk.RIGHT,fill=tk.BOTH) # side是滚动条放置的位置,上下左右。fill是将滚动条沿着y轴填充
    md_enter.pack(fill=tk.Y) # 将文本框填充进窗口
    # 将滚动条与文本框关联
    scroll.config(command=md_enter.yview) # 将文本框关联到滚动条上,滚动条滑动,文本框跟随滑动
    md_enter.config(yscrollcommand=scroll.set) # 将滚动条关联到文本框
    post_btn=ttk.Button(md_win,text='发布',command=lambda:md_post(md_enter.get(),name_enter.get(),title_enter.get())).pack(side=tk.BOTTOM,fill=tk.X)
    md_win.mainloop()

s_win=tk.Tk()
s_win.title('One Blogger')

screenWidth = s_win.winfo_screenwidth()  # 获取显示区域的宽度
screenHeight = s_win.winfo_screenheight()  # 获取显示区域的高度
width = 300  # 设定窗口宽度
height = 165  # 设定窗口高度
left = (screenWidth - width) / 2
top = (screenHeight - height) / 2
s_win.geometry("%dx%d+%d+%d" % (width, height, left, top))
s_win.resizable(0,0)
s_win.overrideredirect(1)

titleA=tk.Label(s_win,text='One Blogger',font=('幼圆',25))
titleA.pack(pady=20)

titleB=tk.Label(s_win,text='博客后台',font=('幼圆',15))
titleB.pack(pady=10)

s_win.update()

time.sleep(2)
s_win.destroy()

if token=='' or user=='' or email=='':
    token_win=tk.Tk()
    token_win.geometry('300x500')
    token_win.title('One Blogger')
    token_win.resizable(0,0)
    s = ttk.Style()
    print(s.theme_names()) #ttk所有主题风格[windows Python 3.8.3 tk 8.6.9]
    #output:('winnative','clam','alt','default','classic','vista','xpnative')
    s.theme_use('vista')
    tk.Label(token_win,text='输入一些必需的信息以继续',font=('幼圆',15)).pack(pady=20)
    tk.Label(token_win,text='GitHub Token',font=('幼圆',10)).pack(pady=10)
    token_enter=ttk.Entry(token_win)
    token_enter.pack(padx=30,fill=tk.X)
    tk.Label(token_win,text='GitHub用户名',font=('幼圆',10)).pack(pady=10)
    user_enter=ttk.Entry(token_win)
    user_enter.pack(padx=30,fill=tk.X)
    tk.Label(token_win,text='GitHub账户邮箱',font=('幼圆',10)).pack(pady=10)
    email_enter=ttk.Entry(token_win)
    email_enter.pack(padx=30,fill=tk.X)
    ttk.Button(token_win,text='继续',command=writeToken).pack(pady=20)
    token_win.mainloop()


win=tk.Tk()
win.geometry('800x450')
win.title('One Blogger')

s = ttk.Style()
print(s.theme_names()) #ttk所有主题风格[windows Python 3.8.3 tk 8.6.9]
#output:('winnative','clam','alt','default','classic','vista','xpnative')
s.theme_use('clam')

ttk.Button(win,text="MarkDown编辑器",command=md).pack()

win.mainloop()

GitHub Pages的存储库里应该放什么?

必需

一个主页 /index.html
一个文件夹,用于存放你发的博客 /post/

可选

错误页面,例如404.html

其他你想要添加的页面,但记得留下入口!

其他你想要添加的任何东西,例如CSS和JS代码

本地的后台路径内应该放什么?

后台程序,代码已公开

settings文件夹,用于存放设置,里面必须有以下文件:

  • email.set,用于存放你的GitHub账户邮箱,不用手动更改除非是已经填写,需要第二次更改。
  • post_formwork.set,用于存放你的博客页面模板,需要手动更改,更改后不会影响以前的内容。以下是几个参数:{title}博客标题,{name}博客名称(页面名称),{content}博客内容(HTML),就算你不想改你至少得有这些东西吧:
    1 <html>
    2 <head>
    3 </head>
    4 <body>
    5 <h1>{title}</h1>
    6 {content}
    7 </body>
    8 </html>
  • token.set,用于存放你的GitHub Token,不用手动更改,除非是已经填写,需要第二次更改,若为空则无法调用API(反正你每次启动是它都会检测,如果为空就会让你填写而不会进入主页面)。
  • user.set,用于存放你的GitHub用户名,不用手动更改,除非是已经填写,需要第二次更改。

后期计划更新

可视化设置界面

主题设置

界面细节优化

增加init.py初始化程序,并在主界面增加入口(有可能是增加一个函数,视情况而定)

所需的第三方库

markdown

requests

1 pip install markdown -i https://pypi.douban.com/simple/
2 pip install requests -i https://pypi.douban.com/simple/
第三方库安装代码

注意

我因为没有腾出存储库,所有还没测试,欢迎大家把测试结果、报错和BUG发到评论区,我如果看见了就会改良。

待存储库腾出来以后,我会用最简陋的网站来测试(HTML自学的,CSS不会,在网上用工具生成的,能力限制,只能用最简陋的了)。

求助

上面说了,我制作网站的能力不行,所以我希望有人能给我提供一个能使用这个博客后台的个人博客网站(或者模板),请提供链接,谢谢!

2.0

增加了初始化功能

增加了链接存储库功能,在博客页面模板中的参数为{linked_repo}

发现并修复了一些设计上的BUG

代码

  1 import requests
  2 import tkinter as tk
  3 import time
  4 from tkinter import ttk  # Normal Tkinter.* widgets are not themed!
  5 from ttkthemes import ThemedTk
  6 import markdown
  7 import tkinter.messagebox as msgbox
  8 import tkinter.filedialog as filebox
  9 
 10 # 读取文件
 11 def open_file(file_path):
 12     with open(file_path, 'wb+') as f:
 13         return f.read()
 14 
 15 def writeToken():
 16     token=token_enter.get()
 17     user=user_enter.get()
 18     email=email_enter.get()
 19     with open("./settings/token.set",'w') as f:
 20         f.write(token)
 21     with open("./settings/user.set",'w') as f:
 22         f.write(user)
 23     with open("./settings/email.set",'w') as f:
 24         f.write(email)
 25     token_win.destroy()
 26 
 27 #读取设置
 28 with open("./settings/token.set",'r') as f:
 29     token=f.read()
 30 with open("./settings/user.set",'r') as f:
 31     user=f.read()
 32 with open("./settings/email.set",'r') as f:
 33     email=f.read()
 34 with open("./settings/post_formwork.set",'r') as f:
 35     post_formwork=f.read()
 36 
 37 
 38 def post(content,name):
 39     global user
 40     upload_file(content,name+".html",user,user+".github.io","post/")
 41 
 42 def md_post(content,name,title,linkedRepo):
 43     html_cont=markdown.Markdown(content)
 44     html=post_formwork.format(title=title,name=name,content=content,linked_repo=linkedRepo)
 45     post(html,name)
 46 
 47 # 将文件转换为base64编码,上传文件必须将文件以base64格式上传
 48 def file_base64(data):
 49     data_b64 = base64.b64encode(data).decode('utf-8')
 50     return data_b64
 51 
 52 
 53 # 上传文件
 54 def upload_file(file_data,file_name,user,repo,path=""):
 55     global token,email
 56     url = "https://api.github.com/repos/"+user+"/"+repo+"/contents/"+path+file_name  # 用户名、库名、路径
 57     headers = {"Authorization": "token " + token}
 58     content = file_base64(file_data)
 59     data = {
 60         "message": "message",
 61         "committer": {
 62             "name": user,
 63             "email": email
 64         },
 65         "content": file_data
 66     }
 67     data = json.dumps(data)
 68     req = requests.put(url=url, data=data, headers=headers)
 69     req.encoding = "utf-8"
 70     re_data = json.loads(req.text)
 71     print(re_data)
 72     print(re_data['content']['sha'])
 73     print("https://cdn.jsdelivr.net/gh/[user]/[repo]/[path]"+file_name)
 74 
 75 def md():
 76     md_win=tk.Tk()
 77     md_win.title('MarkDown编辑器')
 78     tk.Label(md_win,text='博客名称').pack()
 79     name_enter=ttk.Entry(md_win)
 80     name_enter.pack(fill=tk.X)
 81     tk.Label(md_win,text='博客标题').pack()
 82     title_enter=ttk.Entry(md_win)
 83     title_enter.pack(fill=tk.X)
 84     tk.Label(md_win,text='链接的存储库(可选)').pack()
 85     linkedRepo_enter=ttk.Entry(md_win)
 86     linkedRepo_enter.pack(fill=tk.X)
 87     tk.Label(md_win,text='博客内容').pack()
 88     scroll = tk.Scrollbar(md_win)
 89     md_enter=tk.Text(md_win)
 90     # 将滚动条填充
 91     scroll.pack(side=tk.RIGHT,fill=tk.BOTH) # side是滚动条放置的位置,上下左右。fill是将滚动条沿着y轴填充
 92     md_enter.pack(fill=tk.Y) # 将文本框填充进窗口
 93     # 将滚动条与文本框关联
 94     scroll.config(command=md_enter.yview) # 将文本框关联到滚动条上,滚动条滑动,文本框跟随滑动
 95     md_enter.config(yscrollcommand=scroll.set) # 将滚动条关联到文本框
 96     post_btn=ttk.Button(md_win,text='发布',command=lambda:md_post(md_enter.get(),name_enter.get(),title_enter.get(),linkedRepo_enter.get())).pack(side=tk.BOTTOM,fill=tk.X)
 97     md_win.mainloop()
 98 
 99 def init():
100     global user
101     c=msgbox.askokcancel(title = '要继续吗?',message='初始化博客站点将会覆盖以前的所有数据,要继续吗?')
102     if c:
103         site_dir=filebox.askdirectory(title='选择本地博客站点备份并上传')
104         print(site_dir)
105         root,dirs,files=os.walk(file)
106         msgbox.showinfo('进行以下操作','请手动清空(或创建)名为“你的用户名.github.io”的存储库,然后单击确定以继续。')
107         for path in files:
108             with open(site_dir+path,'rb') as f:
109                 content=f.read()
110                 upload_file(content,path,user,user+".github.io","/")
111 
112 s_win=tk.Tk()
113 s_win.title('One Blogger')
114 
115 screenWidth = s_win.winfo_screenwidth()  # 获取显示区域的宽度
116 screenHeight = s_win.winfo_screenheight()  # 获取显示区域的高度
117 width = 300  # 设定窗口宽度
118 height = 165  # 设定窗口高度
119 left = (screenWidth - width) / 2
120 top = (screenHeight - height) / 2
121 s_win.geometry("%dx%d+%d+%d" % (width, height, left, top))
122 s_win.resizable(0,0)
123 s_win.overrideredirect(1)
124 
125 titleA=tk.Label(s_win,text='One Blogger 2',font=('幼圆',25))
126 titleA.pack(pady=20)
127 
128 titleB=tk.Label(s_win,text='博客后台',font=('幼圆',15))
129 titleB.pack(pady=10)
130 
131 ver=tk.Label(s_win,text='后台版本 V2.0',font=('幼圆',10))
132 ver.pack(pady=10)
133 
134 s_win.update()
135 
136 time.sleep(2)
137 s_win.destroy()
138 
139 if token=='' or user=='' or email=='':
140     token_win=tk.Tk()
141     token_win.geometry('300x500')
142     token_win.title('One Blogger')
143     token_win.resizable(0,0)
144     s = ttk.Style()
145     print(s.theme_names()) #ttk所有主题风格[windows Python 3.8.3 tk 8.6.9]
146     #output:('winnative','clam','alt','default','classic','vista','xpnative')
147     s.theme_use('vista')
148     tk.Label(token_win,text='输入一些必需的信息以继续',font=('幼圆',15)).pack(pady=20)
149     tk.Label(token_win,text='GitHub Token',font=('幼圆',10)).pack(pady=10)
150     token_enter=ttk.Entry(token_win)
151     token_enter.pack(padx=30,fill=tk.X)
152     tk.Label(token_win,text='GitHub用户名',font=('幼圆',10)).pack(pady=10)
153     user_enter=ttk.Entry(token_win)
154     user_enter.pack(padx=30,fill=tk.X)
155     tk.Label(token_win,text='GitHub账户邮箱',font=('幼圆',10)).pack(pady=10)
156     email_enter=ttk.Entry(token_win)
157     email_enter.pack(padx=30,fill=tk.X)
158     ttk.Button(token_win,text='继续',command=writeToken).pack(pady=20)
159     token_win.mainloop()
160 
161 
162 win=tk.Tk()
163 win.geometry('800x450')
164 win.title('One Blogger')
165 
166 s = ttk.Style()
167 print(s.theme_names()) #ttk所有主题风格[windows Python 3.8.3 tk 8.6.9]
168 #output:('winnative','clam','alt','default','classic','vista','xpnative')
169 s.theme_use('clam')
170 
171 ttk.Separator(win,orient=tk.HORIZONTAL).pack(pady=7,fill=tk.X)
172 ttk.Button(win,text="MarkDown编辑器",command=md).pack(padx=10,fill=tk.X)
173 ttk.Separator(win,orient=tk.HORIZONTAL).pack(pady=7,fill=tk.X)
174 ttk.Button(win,text="初始化博客站点",command=init).pack(padx=10,fill=tk.X)
175 
176 win.mainloop()

V 2.1.0

增加了设置界面

对部分细节做了更改

因为外观设置需要增加存储设置的文件,所以计划在下一个版本(V 2.1.1)加上

  1 import requests
  2 import tkinter as tk
  3 import time
  4 from tkinter import ttk  # Normal Tkinter.* widgets are not themed!
  5 from ttkthemes import ThemedTk
  6 import markdown
  7 import tkinter.messagebox as msgbox
  8 import tkinter.filedialog as filebox
  9 import webbrowser
 10 
 11 # 读取文件
 12 def open_file(file_path):
 13     with open(file_path, 'wb+') as f:
 14         return f.read()
 15 
 16 def writeToken():
 17     token=token_enter.get()
 18     user=user_enter.get()
 19     email=email_enter.get()
 20     with open("./settings/token.set",'w') as f:
 21         f.write(token)
 22     with open("./settings/user.set",'w') as f:
 23         f.write(user)
 24     with open("./settings/email.set",'w') as f:
 25         f.write(email)
 26     token_win.destroy()
 27 
 28 #读取设置
 29 with open("./settings/token.set",'r') as f:
 30     token=f.read()
 31 with open("./settings/user.set",'r') as f:
 32     user=f.read()
 33 with open("./settings/email.set",'r') as f:
 34     email=f.read()
 35 with open("./settings/post_formwork.set",'r') as f:
 36     post_formwork=f.read()
 37 
 38 
 39 def post(content,name):
 40     global user
 41     upload_file(content,name+".html",user,user+".github.io","post/")
 42 
 43 def md_post(content,name,title,linkedRepo):
 44     html_cont=markdown.Markdown(content)
 45     html=post_formwork.format(title=title,name=name,content=content,linked_repo=linkedRepo)
 46     post(html,name)
 47 
 48 # 将文件转换为base64编码,上传文件必须将文件以base64格式上传
 49 def file_base64(data):
 50     data_b64 = base64.b64encode(data).decode('utf-8')
 51     return data_b64
 52 
 53 
 54 # 上传文件
 55 def upload_file(file_data,file_name,user,repo,path=""):
 56     global token,email
 57     url = "https://api.github.com/repos/"+user+"/"+repo+"/contents/"+path+file_name  # 用户名、库名、路径
 58     headers = {"Authorization": "token " + token}
 59     content = file_base64(file_data)
 60     data = {
 61         "message": "message",
 62         "committer": {
 63             "name": user,
 64             "email": email
 65         },
 66         "content": file_data
 67     }
 68     data = json.dumps(data)
 69     req = requests.put(url=url, data=data, headers=headers)
 70     req.encoding = "utf-8"
 71     re_data = json.loads(req.text)
 72     print(re_data)
 73     print(re_data['content']['sha'])
 74     print("https://cdn.jsdelivr.net/gh/[user]/[repo]/[path]"+file_name)
 75 
 76 def md():
 77     md_win=tk.Tk()
 78     md_win.title('MarkDown编辑器')
 79     tk.Label(md_win,text='博客名称').pack()
 80     name_enter=ttk.Entry(md_win)
 81     name_enter.pack(fill=tk.X)
 82     tk.Label(md_win,text='博客标题').pack()
 83     title_enter=ttk.Entry(md_win)
 84     title_enter.pack(fill=tk.X)
 85     tk.Label(md_win,text='链接的存储库(可选)').pack()
 86     linkedRepo_enter=ttk.Entry(md_win)
 87     linkedRepo_enter.pack(fill=tk.X)
 88     tk.Label(md_win,text='博客内容').pack()
 89     scroll = tk.Scrollbar(md_win)
 90     md_enter=tk.Text(md_win)
 91     # 将滚动条填充
 92     scroll.pack(side=tk.RIGHT,fill=tk.BOTH) # side是滚动条放置的位置,上下左右。fill是将滚动条沿着y轴填充
 93     md_enter.pack(fill=tk.Y) # 将文本框填充进窗口
 94     # 将滚动条与文本框关联
 95     scroll.config(command=md_enter.yview) # 将文本框关联到滚动条上,滚动条滑动,文本框跟随滑动
 96     md_enter.config(yscrollcommand=scroll.set) # 将滚动条关联到文本框
 97     post_btn=ttk.Button(md_win,text='发布',command=lambda:md_post(md_enter.get(),name_enter.get(),title_enter.get(),linkedRepo_enter.get())).pack(side=tk.BOTTOM,fill=tk.X)
 98     md_win.mainloop()
 99 
100 def init():
101     global user
102     c=msgbox.askokcancel(title = '要继续吗?',message='初始化博客站点将会覆盖以前的所有数据,要继续吗?')
103     if c:
104         site_dir=filebox.askdirectory(title='选择本地博客站点备份并上传')
105         print(site_dir)
106         root,dirs,files=os.walk(file)
107         msgbox.showinfo('进行以下操作','手动清空(或创建)名为“你的用户名.github.io”的存储库,然后单击确定以继续。')
108         for path in files:
109             with open(site_dir+path,'rb') as f:
110                 content=f.read()
111                 upload_file(content,path,user,user+".github.io","/")
112 
113 def settings():
114     settings=tk.Tk()
115     settings.title('设置')
116     settings.state("zoomed")
117     # 创建画布
118     about=ttk.LabelFrame(settings,text='关于')
119     about.pack(padx=10,pady=10,fill=tk.X)
120     tk.Label(about,text='One Blogger 2',font=('幼圆',12)).pack(pady=5)
121     tk.Label(about,text='2020 By 人工智障',font=('幼圆',12)).pack(pady=5)
122     tk.Label(about,text='V 2.1.0',font=('幼圆',12)).pack(pady=5)
123     ttk.Button(about,text='作者博客',command=lambda:webbrowser.open("https://www.cnblogs.com/TotoWang/")).pack(pady=5,padx=5)
124     api=ttk.LabelFrame(settings,text='API参数设置')
125     api.pack(padx=10,pady=10,fill=tk.X)
126     ttk.Label(api,text='GitHub Token').pack(pady=10)
127     token_enter=ttk.Entry(api)
128     token_enter.pack(padx=30,fill=tk.X)
129     ttk.Label(api,text='GitHub用户名').pack(pady=10)
130     user_enter=ttk.Entry(api)
131     user_enter.pack(padx=30,fill=tk.X)
132     ttk.Label(api,text='GitHub账户邮箱').pack(pady=10)
133     email_enter=ttk.Entry(api)
134     email_enter.pack(padx=30,fill=tk.X)
135     ttk.Button(api,text='保存',command=writeToken).pack(pady=20)
136     ui=ttk.LabelFrame(settings,text='外观')
137     ui.pack(padx=10,pady=10,fill=tk.X)
138     ttk.Label(ui,text='敬请期待').pack(pady=10)
139     site=ttk.LabelFrame(settings,text='站点设置')
140     site.pack(padx=10,pady=10,fill=tk.X)
141     ttk.Button(site,text="初始化博客站点",command=init).pack(padx=10,pady=10,fill=tk.X)
142     settings.mainloop()
143 
144 s_win=tk.Tk()
145 s_win.title('One Blogger')
146 
147 screenWidth = s_win.winfo_screenwidth()  # 获取显示区域的宽度
148 screenHeight = s_win.winfo_screenheight()  # 获取显示区域的高度
149 width = 300  # 设定窗口宽度
150 height = 165  # 设定窗口高度
151 left = (screenWidth - width) / 2
152 top = (screenHeight - height) / 2
153 s_win.geometry("%dx%d+%d+%d" % (width, height, left, top))
154 s_win.resizable(0,0)
155 s_win.overrideredirect(1)
156 
157 titleA=tk.Label(s_win,text='One Blogger 2',font=('courier new',25))
158 titleA.pack(pady=20)
159 
160 titleB=tk.Label(s_win,text='博客后台',font=('幼圆',15))
161 titleB.pack(pady=10)
162 
163 ver=tk.Label(s_win,text='后台版本 V2.1.0',font=('幼圆',10))
164 ver.pack(pady=10)
165 
166 s_win.update()
167 
168 time.sleep(2)
169 s_win.destroy()
170 
171 if token=='' or user=='' or email=='':
172     token_win=tk.Tk()
173     token_win.geometry('300x500')
174     token_win.title('One Blogger')
175     token_win.resizable(0,0)
176     s = ttk.Style()
177     print(s.theme_names()) #ttk所有主题风格[windows Python 3.8.3 tk 8.6.9]
178     #output:('winnative','clam','alt','default','classic','vista','xpnative')
179     s.theme_use('vista')
180     tk.Label(token_win,text='输入一些必需的信息以继续',font=('幼圆',15)).pack(pady=20)
181     tk.Label(token_win,text='GitHub Token',font=('幼圆',10)).pack(pady=10)
182     token_enter=ttk.Entry(token_win)
183     token_enter.pack(padx=30,fill=tk.X)
184     tk.Label(token_win,text='GitHub用户名',font=('幼圆',10)).pack(pady=10)
185     user_enter=ttk.Entry(token_win)
186     user_enter.pack(padx=30,fill=tk.X)
187     tk.Label(token_win,text='GitHub账户邮箱',font=('幼圆',10)).pack(pady=10)
188     email_enter=ttk.Entry(token_win)
189     email_enter.pack(padx=30,fill=tk.X)
190     ttk.Button(token_win,text='继续',command=writeToken).pack(pady=20)
191     token_win.mainloop()
192 
193 
194 win=tk.Tk()
195 win.geometry('800x450')
196 win.title('One Blogger')
197 
198 s = ttk.Style()
199 print(s.theme_names()) #ttk所有主题风格[windows Python 3.8.3 tk 8.6.9]
200 #output:('winnative','clam','alt','default','classic','vista','xpnative')
201 s.theme_use('clam')
202 
203 ttk.Separator(win,orient=tk.HORIZONTAL).pack(pady=7,fill=tk.X)
204 ttk.Button(win,text="MarkDown编辑器",command=md).pack(padx=10,fill=tk.X)
205 ttk.Separator(win,orient=tk.HORIZONTAL).pack(pady=7,fill=tk.X)
206 ttk.Button(win,text="初始化博客站点",command=init).pack(padx=10,fill=tk.X)
207 ttk.Button(win,text="设置",command=settings).pack(padx=10,fill=tk.X)
208 
209 win.mainloop()
原文地址:https://www.cnblogs.com/TotoWang/p/blog_post.html