python:tkinter + pywebview 初探,简单应用,不是纯粹的 webview应用。

pip install readmdict

pip install pywebview

pip install tkwebview2

安装 MDict 去 MDict | One app for all dictionaries 下载

示例程序 tk_mdx_webview2.py 如下

# -*- coding: utf-8 -*-
import os
import time
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
#import webview
from readmdict import MDX  # pip install readmdict
import win32com.client  # TTS
from tkwebview2.tkwebview2 import WebView2, have_runtime, install_runtime
import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Threading')
from System.Windows.Forms import Control
from System.Threading import Thread,ApartmentState,ThreadStart

speaker = win32com.client.Dispatch("SAPI.SpVoice")
os.chdir("/MDictPC/doc")

def speak():
    """ TTS发音 """
    txt = entry.get()
    if txt.strip() !='':
        speaker.Speak(txt)

def open_mdx():
    filetypes = [('mdx file','.mdx')]
    file1 = filedialog.askopenfilename(initialdir=".", filetypes=filetypes)
    if file1 == '': return
    start_time = time.time()
    path1 = os.path.dirname(file1)
    os.chdir(path1)
    global headwords, items
    # 加载.mdx文件
    fname = os.path.basename(file1)
    mdx = MDX(fname)
    headwords = [*mdx]       # 单词名列表
    items = [*mdx.items()]   # 释义html源码列表
    n = len(headwords)
    m = len(items)
    end_time = time.time()
    print('cost %f second' % (end_time - start_time))
    if n == m:
        var1.set(f'{fname} 加载成功:共{n}条')
    else:
        var1.set(f'ERROR:{fname} 加载失败 {n}!={m}')
        return

def query(self):
    """  输入英文单词,并查询 """
    if not entry.get():
        messagebox.showinfo("请先选择词典","输入单词不能为空")
        return
    txt = entry.get()
    if txt.startswith("http://") or txt.startswith("https://"):
        frame.load_url(txt)
    else:
        prefix(txt)
        query1(txt)
    return

def query1(txt):
    """  查询英文单词 """
    global var1, headwords, frame
    try:
        type(headwords)
    except NameError:
        messagebox.showinfo("提示", "请先选择词典!")
        return
    word = txt.lower().encode()
    word1 = txt.capitalize().encode() # 第1个字母变大写
    try: # 查词,返回单词和html文件
        if word in headwords:
            wordIndex = headwords.index(word)
        else:
            wordIndex = headwords.index(word1)
        word,html = items[wordIndex]
        result = html.decode()
        result = result.replace('<img src="','<img src="data/')
        result = result.replace('"/thumb/','"data/thumb/')
        frame.load_html(result)

    except Exception as e:
        print(e)

def prefix(txt):
    """ 前缀匹配 """
    global var1, headwords
    try:
        type(headwords)
    except NameError:
        print('headwords is undefined.')
        return
    if len(txt) > 2:
        listbox.delete(0, tk.END)
        word = txt.strip().lower() # 字母变小写
        for hw in headwords:
            hws = hw.decode().lower()
            if hws.startswith(word):
                listbox.insert(tk.END, hw.decode())
    else:
        var1.set(f"{txt} input too short")

def selected(self):
    """ 选择列表框 """
    try:
        index = listbox.curselection()
        txt = listbox.get(index,last=None)
        query1(txt)
    except:
        print('listbox index is null.')

def search():
    """ 访问http://localhost:???? """
    txt = entry.get()
    if txt.startswith('http://') or txt.startswith('https://') :
        frame.load_url(txt)
    else:
        prefix(txt)

# main()
# 没有 webview2 runtime 就安装
if not have_runtime():
    install_runtime()
root = tk.Tk()
root.title("查询英文单词")
root.geometry("1000x500")
root.resizable(width=True, height=False)
# 输入框布局
frame1 = tk.Frame(root, width=80, height=30)
frame1.pack(side="top")
entry = tk.Entry(frame1, width=50)
entry.pack(side="left", padx=5, pady=2)
entry.bind("<Return>", query) # 按下回车,执行查单词
button1 = tk.Button(frame1, text="选择词典", command=open_mdx)
button1.pack(side="left", padx=5, pady=2)
button2 = tk.Button(frame1, text="TTS读单词", command=speak)
button2.pack(side="left", padx=5, pady=2)
button3 = tk.Button(frame1, text="访问http", command=search)
button3.pack(side="left", padx=5, pady=2)
# 退出按钮
quit_btn = tk.Button(frame1, text="退出", fg="red", command=root.quit)
quit_btn.pack(side="right", padx=5, pady=2)
# 显示栏
var1 = tk.StringVar()
label = tk.Label(root,textvariable=var1,fg="purple", font="SimSun 12")
var1.set("请先选择词典")
label.pack()
# 列表框
listbox = tk.Listbox(root, width=25, font="Song 12")
listbox.bind('<<ListboxSelect>>', selected)
listbox.pack(side="left", fill='both')
#create WebView2
frame = WebView2(root, 800, 450)
frame.pack(side='right', padx=10, fill='both', expand=True)

root.mainloop()

运行 python tk_mdx_webview2.py

如果通过 frame.load_html(result) 直接写入 HTML,则不能引用其他本地文件路径。
比如:引用 js, css 等本地资源文件,都无法加载。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐