计算器
import tkinter as tk
from tkinter import messagebox
from math import sqrt
class CalcApp:
def __init__(self, root):
self.root = root
self.root.title("综合计算器")
self.mode = tk.StringVar(value="普通计算器")
self.create_menu()
self.norm_frame = tk.Frame(self.root)
self.mort_frame = tk.Frame(self.root)
self.create_norm_calc(self.norm_frame)
self.create_mort_calc(self.mort_frame)
self.norm_frame.grid(row=1, column=0, sticky="nsew")
self.mort_frame.grid(row=1, column=0, sticky="nsew")
self.root.grid_rowconfigure(1, weight=1)
self.root.grid_columnconfigure(0, weight=1)
self.expr = ""
def create_menu(self):
modes = ["普通计算器", "贷款计算器"]
tk.OptionMenu(self.root, self.mode, *modes, command=self.switch_mode).grid(row=0, column=0, padx=10, pady=10)
def switch_mode(self, mode):
if mode == "普通计算器":
self.mort_frame.grid_forget()
self.norm_frame.grid(row=1, column=0, padx=10, pady=10)
else:
self.norm_frame.grid_forget()
self.mort_frame.grid(row=1, column=0, padx=10, pady=10)
def create_norm_calc(self, frame):
self.res = tk.StringVar()
self.display = tk.Text(frame, height=2, font=('Arial', 20), bd=10, wrap=tk.WORD)
self.display.grid(row=0, column=0, columnspan=4, padx=10, pady=10, sticky="nsew")
btns = [
('7', 1, 0), ('8', 1, 1), ('9', 1, 2), ('/', 1, 3),
('4', 2, 0), ('5', 2, 1), ('6', 2, 2), ('*', 2, 3),
('1', 3, 0), ('2', 3, 1), ('3', 3, 2), ('-', 3, 3),
('0', 4, 0), ('.', 4, 1), ('+', 4, 2), ('=', 4, 3),
('C', 5, 0), ('←', 5, 1), ('sqrt', 5, 2), ('%', 5, 3),
('(', 6, 0), (')', 6, 1), ('^', 6, 2), ('1/x', 6, 3)
]
for (text, row, col) in btns:
btn = tk.Button(frame, text=text, padx=20, pady=20, font=('Arial', 18),
command=lambda t=text: self.on_btn_click(t))
btn.grid(row=row, column=col, sticky="nsew")
for i in range(7):
frame.grid_rowconfigure(i, weight=1)
for i in range(4):
frame.grid_columnconfigure(i, weight=1)
def tokenize(self, expr):
tokens = []
current_num = []
i = 0
while i < len(expr):
char = expr[i]
if char.isdigit() or char == '.':
current_num.append(char)
else:
if current_num:
tokens.append(''.join(current_num))
current_num = []
if char in '+-*/^()':
tokens.append(char)
elif char == 's' and expr[i:i + 4] == 'sqrt':
tokens.append('sqrt')
i += 3
elif char == '1' and i + 1 < len(expr) and expr[i + 1] == '/':
tokens.append('1/x')
i += 1
elif char == '%':
tokens.append('%')
i += 1
if current_num:
tokens.append(''.join(current_num))
return tokens
def precedence(self, op) :
if op == 'sqrt':
return 4
if op in ('+', '-'):
return 1
if op in ('*', '/', '%'):
return 2
if op == '^':
return 3
return 0
def apply_op(self, a, b, op):
if op == '+':
return a + b
if op == '-':
return a - b
if op == '*':
return a * b
if op == '/':
return a / b
if op == '^':
return a ** b
if op == '%':
return a % b
if op == '1/x':
return 1 / b
def perform_op(self):
operator = self.op_stack.pop()
if operator == 'sqrt':
val = self.num_stack.pop()
self.num_stack.append(sqrt(val))
elif operator == '1/x':
val = self.num_stack.pop()
self.num_stack.append(1 / val)
else:
right = self.num_stack.pop()
left = self.num_stack.pop()
self.num_stack.append(self.apply_op(left, right, operator))
def evaluate(self):
self.num_stack = []
self.op_stack = []
tokens = self.tokenize(self.expr)
for token in tokens:
if token.isdigit() or '.' in token:
self.num_stack.append(float(token))
elif token in '+-*/^%':
while (self.op_stack and self.precedence(self.op_stack[-1]) >= self.precedence(token)):
self.perform_op()
self.op_stack.append(token)
elif token == '(':
self.op_stack.append(token)
elif token == ')':
while self.op_stack and self.op_stack[-1] != '(':
self.perform_op()
self.op_stack.pop() # 弹出'('
elif token == 'sqrt':
self.op_stack.append('sqrt')
elif token == '1/x':
self.op_stack.append('1/x')
while self.op_stack:
self.perform_op()
self.expr = str(self.num_stack.pop())
def on_btn_click(self, char):
if char == '=':
try:
self.evaluate()
except Exception:
self.expr = "Error"
elif char == 'C':
self.expr = ""
elif char == '←':
self.expr = self.expr[:-1]
else:
self.expr += str(char)
self.display.delete('1.0', tk.END)
self.display.insert(tk.END, self.expr)
def create_mort_calc(self, frame):
self.pay_type = tk.StringVar(value="等额本息")
self.years = tk.StringVar()
self.amount = tk.StringVar()
self.rate = tk.StringVar()
self.monthly_pay = tk.StringVar()
self.total_int = tk.StringVar()
self.total_pay = tk.StringVar()
tk.Label(frame, text="还款方式:").grid(row=0, column=0, padx=5, pady=5, sticky='w')
tk.Radiobutton(frame, text="等额本息", variable=self.pay_type, value="等额本息").grid(row=0, column=1)
tk.Radiobutton(frame, text="等额本金", variable=self.pay_type, value="等额本金").grid(row=0, column=2)
tk.Label(frame, text="贷款年限(年):").grid(row=1, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.years).grid(row=1, column=1, columnspan=2)
tk.Label(frame, text="贷款金额(万元):").grid(row=2, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.amount).grid(row=2, column=1, columnspan=2)
tk.Label(frame, text="贷款利率(%):").grid(row=3, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.rate).grid(row=3, column=1, columnspan=2)
tk.Button(frame, text="计算", command=self.calc_mort).grid(row=4, column=0, columnspan=2, pady=10)
tk.Button(frame, text="重置", command=self.reset_mort).grid(row=4, column=2, pady=10)
tk.Label(frame, text="月均还款(元):").grid(row=5, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.monthly_pay, state='readonly').grid(row=5, column=1, columnspan=2)
tk.Label(frame, text="利息总额(元):").grid(row=6, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.total_int, state='readonly').grid(row=6, column=1, columnspan=2)
tk.Label(frame, text="还款总额(元):").grid(row=7, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.total_pay, state='readonly').grid(row=7, column=1, columnspan=2)
def calc_mort(self):
"""贷款计算器计算逻辑"""
try:
yrs = int(self.years.get())
princ = float(self.amount.get()) * 10000 # 万元转换为元
rate_yr = float(self.rate.get()) / 100 # 转换为小数利率
months = yrs * 12 # 贷款总月数
rate_mth = rate_yr / 12 # 月利率
if self.pay_type.get() == "等额本息":
# 等额本息公式
m_pay = princ * rate_mth * ((1 + rate_mth) ** months) / (((1 + rate_mth) ** months) - 1)
total_pay = m_pay * months
total_int = total_pay - princ
else:
# 等额本金公式
m_pay = princ / months + (princ * rate_mth)
total_pay = (months + 1) * princ * rate_mth / 2 + princ
total_int = total_pay - princ
self.monthly_pay.set(f"{m_pay:.2f}")
self.total_int.set(f"{total_int:.2f}")
self.total_pay.set(f"{total_pay:.2f}")
except ValueError:
messagebox.showerror("输入错误", "请输入有效的数字")
def reset_mort(self):
"""重置贷款计算器输入和输出"""
self.years.set("")
self.amount.set("")
self.rate.set("")
self.monthly_pay.set("")
self.total_int.set("")
self.total_pay.set("")
if __name__ == "__main__":
root = tk.Tk()
app = CalcApp(root)
root.mainloop()
拼图
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import random
class MyPuzzleGame:
def __init__(self, root):
self.root = root
self.root.title("拼图游戏")
self.grid_size = 3 # Default grid size
self.tile_size = 150 # Size of each tile
self.image_path = None
self.original_image = None
self.tiles = {} # Stores tiles for each grid size
self.correct_positions = []
self.current_positions = []
self.selected_tile = None
self.time_remaining = 0
self.timer_label = None
self.timer_id = None
self.manual_check = False # Track manual "Check Puzzle" clicks
self.setup_ui()
def setup_ui(self):
self.canvas = tk.Canvas(self.root, width=450, height=450, bg="white")
self.canvas.grid(row=0, column=0, columnspan=5)
tk.Button(self.root, text="加载图片", command=self.load_image).grid(row=1, column=0)
tk.Button(self.root, text="重置拼图", command=self.reset_puzzle).grid(row=1, column=1)
tk.Button(self.root, text="查看原图", command=self.show_original_image).grid(row=1, column=2)
tk.Button(self.root, text="检查拼图", command=self.check_puzzle).grid(row=1, column=3)
self.timer_label = tk.Label(self.root, text="倒计时: 00:00")
self.timer_label.grid(row=1, column=4)
self.time_var = tk.StringVar(self.root)
self.time_var.set("30s")
tk.OptionMenu(self.root, self.time_var, "30s", "1min", "3min", "5min", command=self.set_timer).grid(row=2, column=4)
# Difficulty selection
tk.Button(self.root, text="3x3", command=lambda: self.change_difficulty(3)).grid(row=2, column=0)
tk.Button(self.root, text="4x4", command=lambda: self.change_difficulty(4)).grid(row=2, column=1)
tk.Button(self.root, text="5x5", command=lambda: self.change_difficulty(5)).grid(row=2, column=2)
def change_difficulty(self, size):
self.grid_size = size
self.tile_size = 450 // size # Adjust tile size according to grid size
self.reset_puzzle()
def set_timer(self, _=None):
if self.timer_id:
self.root.after_cancel(self.timer_id)
times = {"30s": 30, "1min": 60, "3min": 180, "5min": 300}
self.time_remaining = times[self.time_var.get()]
self.update_timer()
def update_timer(self):
mins, secs = divmod(self.time_remaining, 60)
self.timer_label.config(text=f"倒计时: {mins:02d}:{secs:02d}")
if self.time_remaining > 0:
self.time_remaining -= 1
self.timer_id = self.root.after(1000, self.update_timer)
else:
messagebox.showinfo("时间到", "很遗憾,您没有在规定时间内完成拼图。")
self.reset_puzzle()
def load_image(self):
self.image_path = filedialog.askopenfilename(title="选择图片",
filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])
if not self.image_path:
return
self.original_image = Image.open(self.image_path).resize((450, 450))
self.setup_tiles()
self.display_tiles()
def setup_tiles(self):
self.tiles[self.grid_size] = []
self.correct_positions = []
self.current_positions = []
for i in range(self.grid_size):
row = []
for j in range(self.grid_size):
x, y = j * self.tile_size, i * self.tile_size
crop = self.original_image.crop((x, y, x + self.tile_size, y + self.tile_size))
photo = ImageTk.PhotoImage(crop)
row.append(photo)
self.correct_positions.append((i, j))
self.tiles[self.grid_size].append(row)
self.current_positions = self.correct_positions[:]
random.shuffle(self.current_positions)
def display_tiles(self):
self.canvas.delete("all")
for idx, pos in enumerate(self.current_positions):
x, y = pos[1] * self.tile_size, pos[0] * self.tile_size
self.canvas.create_image(x, y, image=self.tiles[self.grid_size][self.correct_positions[idx][0]][
self.correct_positions[idx][1]], anchor=tk.NW, tags=f"tile{idx}")
self.canvas.bind("<Button-1>", self.on_tile_press)
self.canvas.bind("<B1-Motion>", self.on_tile_drag)
self.canvas.bind("<ButtonRelease-1>", self.on_tile_release)
def on_tile_press(self, event):
x, y = event.x, event.y
for idx, pos in enumerate(self.current_positions):
tile_x, tile_y = pos[1] * self.tile_size, pos[0] * self.tile_size
if tile_x <= x < tile_x + self.tile_size and tile_y <= y < tile_y + self.tile_size:
self.selected_tile = idx
self.offset_x, self.offset_y = x - tile_x, y - tile_y
break
def on_tile_drag(self, event):
if self.selected_tile is not None:
x, y = event.x - self.offset_x, event.y - self.offset_y
self.canvas.coords(f"tile{self.selected_tile}", x, y)
def on_tile_release(self, event):
if self.selected_tile is not None:
target_pos = self.correct_positions[self.selected_tile]
closest_idx = self.find_closest_tile(event.x, event.y)
if closest_idx is not None:
# Swap positions in current_positions
self.current_positions[self.selected_tile], self.current_positions[closest_idx] = \
self.current_positions[closest_idx], self.current_positions[self.selected_tile]
self.display_tiles() # Re-display tiles to reset positions after release
if self.is_puzzle_complete():
messagebox.showinfo("成功", "您完成了拼图!")
self.selected_tile = None
def find_closest_tile(self, x, y):
for idx, pos in enumerate(self.current_positions):
tile_x, tile_y = pos[1] * self.tile_size + self.tile_size // 2, pos[0] * self.tile_size + self.tile_size // 2
if abs(tile_x - x) < self.tile_size // 2 and abs(tile_y - y) < self.tile_size // 2:
return idx
return None
def reset_puzzle(self):
if self.timer_id:
self.root.after_cancel(self.timer_id)
self.setup_tiles()
self.display_tiles()
self.set_timer()
def show_original_image(self):
if self.original_image:
top = tk.Toplevel(self.root)
top.title("原图")
img = ImageTk.PhotoImage(self.original_image)
img_label = tk.Label(top, image=img)
img_label.image = img # Keep reference to avoid garbage-collection
img_label.pack()
def check_puzzle(self):
self.manual_check = True # Mark that "Check Puzzle" was clicked
if self.is_puzzle_complete():
messagebox.showinfo("成功", "您完成了拼图!")
elif self.manual_check:
messagebox.showinfo("未完成", "拼图未完成,请继续努力。")
self.manual_check = False
def is_puzzle_complete(self):
return self.current_positions == self.correct_positions
if __name__ == "__main__":
root = tk.Tk()
game = MyPuzzleGame(root)
root.mainloop()
多文本编辑器
import tkinter as tk
from tkinter import filedialog, font, simpledialog, messagebox, ttk
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
class SimpleMDIExample:
def __init__(self, root):
self.root = root
self.root.title('Simple Multi-Tab Editor')
# Notebook for tabs
self.notebook = ttk.Notebook(root)
self.notebook.pack(fill=tk.BOTH, expand=True)
# Initialize menu and add the first tab
self.current_language = "English"
self.languages = self.load_languages()
self.font_options = ["Microsoft YaHei", "Arial", "Times New Roman", "Courier New"]
self.size_options = [10, 12, 14, 16, 18, 20]
self.file_paths = {} # Dictionary to store file path for each tab
self.load_menu()
self.add_tab()
def load_languages(self):
return {
"English": {
"file": "File",
"new": "New",
"open": "Open",
"save": "Save",
"edit": "Edit",
"undo": "Undo",
"redo": "Redo",
"cut": "Cut",
"copy": "Copy",
"paste": "Paste",
"find": "Find",
"replace": "Replace",
"format": "Format",
"font": "Font",
"font_size": "Font Size",
"bold": "Bold",
"italic": "Italic",
"underline": "Underline",
"align": "Align",
"align_left": "Left Align",
"align_center": "Center Align",
"align_right": "Right Align",
"settings": "Settings",
"language": "Language",
"export_pdf": "Export as PDF",
"exit": "Exit"
},
"中文": {
"file": "文件",
"new": "新建",
"open": "打开",
"save": "保存",
"edit": "编辑",
"undo": "撤销",
"redo": "重做",
"cut": "剪切",
"copy": "复制",
"paste": "粘贴",
"find": "查找",
"replace": "替换",
"format": "格式",
"font": "字体",
"font_size": "字体大小",
"bold": "加粗",
"italic": "斜体",
"underline": "下划线",
"align": "对齐",
"align_left": "左对齐",
"align_center": "居中对齐",
"align_right": "右对齐",
"settings": "设置",
"language": "语言",
"export_pdf": "导出为PDF",
"exit": "退出"
}
}
def load_menu(self):
menu = tk.Menu(self.root)
self.root.config(menu=menu)
file_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label=self.languages[self.current_language]["file"], menu=file_menu)
file_menu.add_command(label=self.languages[self.current_language]["new"], command=self.add_tab)
file_menu.add_command(label=self.languages[self.current_language]["open"], command=self.open_file)
file_menu.add_command(label=self.languages[self.current_language]["save"], command=self.save_file)
file_menu.add_command(label=self.languages[self.current_language]["export_pdf"], command=self.export_as_pdf)
edit_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label=self.languages[self.current_language]["edit"], menu=edit_menu)
edit_menu.add_command(label=self.languages[self.current_language]["undo"],
command=lambda: self.get_current_text_widget().event_generate('<<Undo>>'))
edit_menu.add_command(label=self.languages[self.current_language]["redo"],
command=lambda: self.get_current_text_widget().event_generate('<<Redo>>'))
edit_menu.add_separator()
edit_menu.add_command(label=self.languages[self.current_language]["cut"],
command=lambda: self.get_current_text_widget().event_generate('<<Cut>>'))
edit_menu.add_command(label=self.languages[self.current_language]["copy"],
command=lambda: self.get_current_text_widget().event_generate('<<Copy>>'))
edit_menu.add_command(label=self.languages[self.current_language]["paste"],
command=lambda: self.get_current_text_widget().event_generate('<<Paste>>'))
edit_menu.add_command(label=self.languages[self.current_language]["find"], command=self.find_text)
edit_menu.add_command(label=self.languages[self.current_language]["replace"], command=self.replace_text)
format_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label=self.languages[self.current_language]["format"], menu=format_menu)
format_menu.add_command(label=self.languages[self.current_language]["font"], command=self.select_font)
format_menu.add_command(label=self.languages[self.current_language]["font_size"], command=self.select_font_size)
format_menu.add_command(label=self.languages[self.current_language]["bold"], command=self.set_bold)
format_menu.add_command(label=self.languages[self.current_language]["italic"], command=self.set_italic)
format_menu.add_command(label=self.languages[self.current_language]["underline"], command=self.set_underline)
align_menu = tk.Menu(format_menu, tearoff=0)
format_menu.add_cascade(label=self.languages[self.current_language]["align"], menu=align_menu)
align_menu.add_command(label=self.languages[self.current_language]["align_left"], command=lambda: self.set_alignment("left"))
align_menu.add_command(label=self.languages[self.current_language]["align_center"], command=lambda: self.set_alignment("center"))
align_menu.add_command(label=self.languages[self.current_language]["align_right"], command=lambda: self.set_alignment("right"))
settings_menu = tk.Menu(menu, tearoff=0)
menu.add_cascade(label=self.languages[self.current_language]["settings"], menu=settings_menu)
language_menu = tk.Menu(settings_menu, tearoff=0)
settings_menu.add_cascade(label=self.languages[self.current_language]["language"], menu=language_menu)
language_menu.add_command(label="English", command=lambda: self.switch_language("English"))
language_menu.add_command(label="中文", command=lambda: self.switch_language("中文"))
settings_menu.add_command(label=self.languages[self.current_language]["exit"], command=self.root.quit)
def switch_language(self, language):
self.current_language = language
self.load_menu()
def add_tab(self, title="Untitled"):
frame = ttk.Frame(self.notebook)
frame.pack(fill=tk.BOTH, expand=True)
text_area = tk.Text(frame, wrap=tk.WORD, undo=True, font=("Microsoft YaHei", 12))
text_area.pack(fill=tk.BOTH, expand=True)
text_area.tag_configure("left", justify="left")
text_area.tag_configure("center", justify="center")
text_area.tag_configure("right", justify="right")
# Add a close button to the tab title
tab_id = self.notebook.tabs()[-1] if self.notebook.tabs() else 0
title_with_close = f"{title} ✕"
self.notebook.add(frame, text=title_with_close)
self.notebook.select(frame)
# Add close functionality
self.file_paths[frame] = None
self.notebook.bind("<ButtonRelease-1>", self.on_close_click)
def on_close_click(self, event):
x, y = event.x, event.y
current_index = self.notebook.index("@%d,%d" % (x, y))
tab_text = self.notebook.tab(current_index, "text")
# Check if the click was on the close button part (✕)
if "✕" in tab_text and x > self.notebook.bbox(current_index)[2] - 20:
frame = self.notebook.nametowidget(self.notebook.tabs()[current_index])
del self.file_paths[frame]
self.notebook.forget(current_index)
def get_current_text_widget(self):
current_tab = self.notebook.select()
current_frame = self.notebook.nametowidget(current_tab)
text_widget = current_frame.winfo_children()[0]
return text_widget
def set_alignment(self, alignment):
text_widget = self.get_current_text_widget()
selected_text = text_widget.tag_ranges("sel")
if selected_text:
text_widget.tag_remove("left", "1.0", tk.END)
text_widget.tag_remove("center", "1.0", tk.END)
text_widget.tag_remove("right", "1.0", tk.END)
text_widget.tag_add(alignment, "sel.first", "sel.last")
else:
messagebox.showwarning("Warning", "No text selected!")
def open_file(self):
file_path = filedialog.askopenfilename(filetypes=[("Text files", "*.txt")])
if file_path:
self.add_tab(title=file_path.split('/')[-1])
text_widget = self.get_current_text_widget()
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
text_widget.insert("1.0", content)
current_tab = self.notebook.select()
self.file_paths[self.notebook.nametowidget(current_tab)] = file_path
def save_file(self):
current_tab = self.notebook.select()
text_widget = self.get_current_text_widget()
content = text_widget.get("1.0", tk.END).strip()
file_path = self.file_paths[self.notebook.nametowidget(current_tab)]
if not file_path:
file_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
if not file_path:
return
self.file_paths[self.notebook.nametowidget(current_tab)] = file_path
self.notebook.tab(current_tab, text=file_path.split('/')[-1])
with open(file_path, 'w', encoding='utf-8') as file:
file.write(content)
def export_as_pdf(self):
text_widget = self.get_current_text_widget()
content = text_widget.get("1.0", tk.END).strip()
file_path = filedialog.asksaveasfilename(filetypes=[("PDF files", "*.pdf")])
if file_path:
if not file_path.endswith('.pdf'):
file_path += '.pdf'
self.save_text_as_pdf(file_path, content)
def save_text_as_pdf(self, file_path, text):
c = canvas.Canvas(file_path, pagesize=letter)
text = text.split('\n')
text_height = 750
for line in text:
c.drawString(72, text_height, line)
text_height -= 12
c.save()
def select_font(self):
font_selection = simpledialog.askstring("Select Font", "Choose a font:\n" + "\n".join(self.font_options))
if font_selection in self.font_options:
text_widget = self.get_current_text_widget()
selected_range = text_widget.tag_ranges("sel")
if selected_range:
text_widget.tag_configure("custom_font", font=(font_selection, 12))
text_widget.tag_add("custom_font", selected_range[0], selected_range[1])
else:
messagebox.showwarning("Warning", "No text selected!")
def select_font_size(self):
size_selection = simpledialog.askstring("Select Font Size",
"Choose a size:\n" + ", ".join(map(str, self.size_options)))
if size_selection.isdigit() and int(size_selection) in self.size_options:
text_widget = self.get_current_text_widget()
selected_range = text_widget.tag_ranges("sel")
if selected_range:
text_widget.tag_configure("custom_size", font=("Microsoft YaHei", int(size_selection)))
text_widget.tag_add("custom_size", selected_range[0], selected_range[1])
else:
messagebox.showwarning("Warning", "No text selected!")
def set_bold(self):
text_widget = self.get_current_text_widget()
bold_font = font.Font(text_widget, text_widget.cget("font"))
bold_font.config(weight="bold")
text_widget.tag_configure("bold", font=bold_font)
try:
text_widget.tag_add("bold", "sel.first", "sel.last")
except tk.TclError:
messagebox.showwarning("Warning", "No text selected!")
def set_italic(self):
text_widget = self.get_current_text_widget()
italic_font = font.Font(text_widget, text_widget.cget("font"))
italic_font.config(slant="italic")
text_widget.tag_configure("italic", font=italic_font)
try:
text_widget.tag_add("italic", "sel.first", "sel.last")
except tk.TclError:
messagebox.showwarning("Warning", "No text selected!")
def set_underline(self):
text_widget = self.get_current_text_widget()
underline_font = font.Font(text_widget, text_widget.cget("font"))
underline_font.config(underline=True)
text_widget.tag_configure("underline", font=underline_font)
try:
text_widget.tag_add("underline", "sel.first", "sel.last")
except tk.TclError:
messagebox.showwarning("Warning", "No text selected!")
def find_text(self):
text_widget = self.get_current_text_widget()
search_query = simpledialog.askstring("Find", self.languages[self.current_language]["find"])
if search_query:
start = '1.0'
while True:
start = text_widget.search(search_query, start, stopindex=tk.END)
if not start:
break
end = f"{start}+{len(search_query)}c"
text_widget.tag_add('highlight', start, end)
start = end
text_widget.tag_config('highlight', background='yellow')
def replace_text(self):
text_widget = self.get_current_text_widget()
find_query = simpledialog.askstring("Find", self.languages[self.current_language]["find"])
replace_query = simpledialog.askstring("Replace with", self.languages[self.current_language]["replace"])
if find_query and replace_query:
content = text_widget.get("1.0", tk.END).replace(find_query, replace_query)
text_widget.delete("1.0", tk.END)
text_widget.insert("1.0", content)
if __name__ == "__main__":
root = tk.Tk()
app = SimpleMDIExample(root)
root.mainloop()