还不能够实现所有组件随分辨率自动变化
| |
| from tkinter import * |
| import win32api, win32con |
| |
| |
| width = win32api.GetSystemMetrics(win32con.SM_CXSCREEN) |
| height = win32api.GetSystemMetrics(win32con.SM_CYSCREEN) |
| |
| |
| root = Tk() |
| root.geometry("%dx%d" %(width, height)) |
| root.resizable(False, False) |
| root.mainloop() |
| |
| from tkinter import * |
| root = Tk() |
| root.state("zoomed") |
| root.mainloop() |
可以结合一个python任意区域截图的案例进行分析:
| |
| |
| |
| |
| |
| |
| from win32 import win32api, win32gui, win32print |
| from win32.lib import win32con |
| from win32.win32api import GetSystemMetrics |
| import tkinter as tk |
| from PIL import ImageGrab |
| from tkinter import * |
| from tkinter import filedialog, scrolledtext, messagebox |
| import numpy as np |
| import matplotlib |
| import matplotlib.pyplot as plt |
| from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg |
| from PIL import Image, ImageTk |
| matplotlib.use('TkAgg') |
| |
| global photo |
| global thDim |
| global filepath |
| global point1, point2 |
| global afterHandler |
| |
| |
| class MainWindow(Tk): |
| def __init__(self, master=None): |
| super().__init__(master) |
| global photo |
| global thDim |
| photo = None |
| thDim = None |
| self.master = master |
| self.title("DataCollect") |
| self.state("zoomed") |
| self.pw1 = PanedWindow(self, orient=VERTICAL, sashrelief="sunken") |
| self.pw1.pack(fill=BOTH) |
| self.pw2 = PanedWindow(self.pw1, orient=HORIZONTAL, width=1110, height=813, sashrelief="sunken") |
| self.fr2 = Frame(self.pw2, width=960) |
| self.fr3 = Frame(self.pw2, width=960) |
| self.fr3.place(x=25, y=15) |
| self.fig = plt.figure(figsize=(9.5, 7.15)) |
| self.ax = plt.subplot(projection='3d') |
| self.fig.add_axes(self.ax) |
| self.canvas = FigureCanvasTkAgg(self.fig, master=self.fr3) |
| self.canvas.draw() |
| self.canvas.get_tk_widget().place(x=5, y=5) |
| self.fr1 = Frame(self.pw1, width=800, height=190) |
| self.pw1.add(self.pw2) |
| self.pw1.add(self.fr1) |
| self.pw2.add(self.fr2) |
| self.pw2.add(self.fr3) |
| self.Button_open = Button(self.fr2, text="打开图片", width=8, font=("等线", 20, "bold"), command=self.getfile) |
| self.Button_open.place(x=130, y=740) |
| self.Button_screen = Button(self.fr2, text="开始截图", width=8, font=("等线", 20, "bold"), command=ScreenShot) |
| self.Button_screen.place(x=280, y=740) |
| self.Button_add = Button(self.fr2, text="导入数据", width=8, font=("等线", 20, "bold"), command=self.saveData) |
| self.Button_add.place(x=690, y=740) |
| self.Button_update1 = Button(self.fr3, text="更新图像", width=8, font=("等线", 20, "bold"), command=self.draw3Dim) |
| self.Button_update1.place(x=200, y=740) |
| self.Button_update2 = Button(self.fr3, text="更新文档", width=8, font=("等线", 20, "bold"), command=self.getData) |
| self.Button_update2.place(x=560, y=740) |
| self.Pane_left = Label(self.fr2, image=photo) |
| self.Pane_left.place(x=0, y=0) |
| self.Pane_right = Label(self.fr3, image=thDim) |
| self.Pane_right.place(x=0, y=0) |
| self.Pane_down = Label(self.fr1, height=190, width=800) |
| self.Pane_down.place(x=0, y=0) |
| self.scroll = Scrollbar(self.Pane_down) |
| self.layerNum = Label(self.fr2, text="预测层数:", font=('等线', 20), width=9) |
| self.layerNum.place(x=440, y=745) |
| self.var = StringVar() |
| self.num = Entry(self.fr2, width=15, textvariable=self.var) |
| self.num.place(x=570, y=752) |
| global afterHandler |
| afterHandler = self.after(100, self.draw3Dim) |
| self.protocol("WM_DELETE_WINDOW", self.on_closing) |
| |
| |
| def getfile(self): |
| global filepath |
| filepath = filedialog.askopenfilename(title='选择文件', filetypes=[('BMP', '*.bmp'), ('All Files', '*')]) |
| img = Image.open(filepath) |
| width, height = img.size |
| img = img.resize((958, int(958 / width * height))) |
| |
| global photo |
| photo = ImageTk.PhotoImage(img) |
| self.Pane_left.configure(image=photo) |
| self.Pane_left.image = photo |
| |
| def saveData(self): |
| img = Image.open('./ScreenShot.bmp') |
| width = img.size[0] |
| height = img.size[1] |
| pix = img.load() |
| fname = open('./rgbData.txt', "a") |
| for i in range(0, width): |
| for j in range(0, height): |
| fname.write(str(pix[i, j][0]) + ',' + str(pix[i, j][1]) + ',' + str(pix[i, j][2]) + ',' + str(self.num.get()) + '\n') |
| |
| |
| def getData(self): |
| txt = scrolledtext.ScrolledText(self.Pane_down, width=1110, height=106, font=("宋体", 10)) |
| txt.place(x=0, y=0) |
| f = open('./rgbData.txt') |
| s = f.read() |
| txt.insert(END, s) |
| scroll = Scrollbar(self.Pane_down, orient=VERTICAL, takefocus=0.5) |
| scroll.place(relwidth=0.05, relheight=1, relx=0.9375, rely=0) |
| scroll.config(command=txt.yview) |
| txt.config(yscrollcommand=scroll.set) |
| |
| |
| def draw3Dim(self): |
| |
| data_path = './rgbData.txt' |
| data = np.loadtxt(data_path, dtype=int, delimiter=',') |
| x, y = np.split(data, (3,), axis=1) |
| x0 = x[:, 0] |
| y0 = x[:, 1] |
| z0 = x[:, 2] |
| num = y[:, 0] |
| self.ax.set_xlim(0, 255) |
| self.ax.set_ylim(0, 255) |
| self.ax.set_zlim(0, 255) |
| for i in range(len(num)): |
| |
| if num[i] == 0: |
| self.ax.scatter(x0[i], y0[i], z0[i], c='b') |
| elif num[i] == 1: |
| self.ax.scatter(x0[i], y0[i], z0[i], c='c') |
| elif num[i] == 2: |
| self.ax.scatter(x0[i], y0[i], z0[i], c='g') |
| elif num[i] == 3: |
| self.ax.scatter(x0[i], y0[i], z0[i], c='k') |
| elif num[i] == 4: |
| self.ax.scatter(x0[i], y0[i], z0[i], c='m') |
| elif num[i] == 5: |
| self.ax.scatter(x0[i], y0[i], z0[i], c='r') |
| self.ax.set_xlabel('R') |
| self.ax.set_ylabel('G') |
| self.ax.set_zlabel('B') |
| self.canvas.draw() |
| |
| |
| def on_closing(self): |
| self.after_cancel(afterHandler) |
| answer = messagebox.askokcancel("退出", "确定退出吗?") |
| if answer: |
| plt.close('all') |
| self.destroy() |
| else: |
| self.after(1000, self.draw3Dim) |
| |
| |
| class Box: |
| def __init__(self): |
| self.start_x = None |
| self.start_y = None |
| self.end_x = None |
| self.end_y = None |
| |
| def isNone(self): |
| return self.start_x is None or self.end_x is None |
| |
| def setStart(self, x, y): |
| self.start_x = x |
| self.start_y = y |
| |
| def setEnd(self, x, y): |
| self.end_x = x |
| self.end_y = y |
| |
| def box(self): |
| lt_x = min(self.start_x, self.end_x) |
| lt_y = min(self.start_y, self.end_y) |
| rb_x = max(self.start_x, self.end_x) |
| rb_y = max(self.start_y, self.end_y) |
| return lt_x, lt_y, rb_x, rb_y |
| |
| def center(self): |
| center_x = (self.start_x + self.end_x) / 2 |
| center_y = (self.start_y + self.end_y) / 2 |
| return center_x, center_y |
| |
| |
| class SelectionArea: |
| def __init__(self, canvas: tk.Canvas): |
| self.canvas = canvas |
| self.area_box = Box() |
| |
| def empty(self): |
| return self.area_box.isNone() |
| |
| def setStartPoint(self, x, y): |
| self.canvas.delete('area', 'lt_txt', 'rb_txt') |
| self.area_box.setStart(x, y) |
| |
| self.canvas.create_text( |
| x, y - 10, text=f'({x}, {y})', fill='red', tag='lt_txt') |
| |
| def updateEndPoint(self, x, y): |
| self.area_box.setEnd(x, y) |
| self.canvas.delete('area', 'rb_txt') |
| box_area = self.area_box.box() |
| |
| self.canvas.create_rectangle( |
| *box_area, fill='black', outline='red', width=2, tags="area") |
| self.canvas.create_text( |
| x, y + 10, text=f'({x}, {y})', fill='red', tag='rb_txt') |
| |
| |
| class ScreenShot(): |
| def __init__(self, scaling_factor=2): |
| self.win = tk.Tk() |
| |
| self.width = 960 |
| self.height = 813 |
| |
| |
| self.win.overrideredirect(True) |
| self.win.attributes('-alpha', 0.1) |
| |
| self.is_selecting = False |
| |
| |
| self.win.bind('<KeyPress-Escape>', self.exit) |
| self.win.bind('<KeyPress-Return>', self.confirmScreenShot) |
| self.win.bind('<Button-1>', self.selectStart) |
| self.win.bind('<ButtonRelease-1>', self.selectDone) |
| self.win.bind('<Motion>', self.changeSelectionArea) |
| self.canvas = tk.Canvas(self.win, width=self.width, |
| height=self.height) |
| self.canvas.pack() |
| self.area = SelectionArea(self.canvas) |
| self.win.mainloop() |
| |
| def exit(self, event): |
| self.win.destroy() |
| |
| def clear(self): |
| self.canvas.delete('area', 'lt_txt', 'rb_txt') |
| self.win.attributes('-alpha', 0) |
| |
| def captureImage(self): |
| if self.area.empty(): |
| return None |
| else: |
| box_area = [x for x in self.area.area_box.box()] |
| self.clear() |
| print(f'Grab: {box_area}') |
| img = ImageGrab.grab(box_area) |
| return img |
| |
| def confirmScreenShot(self, event): |
| img = self.captureImage() |
| if img is not None: |
| img.show() |
| img.save('./ScreenShot.bmp') |
| self.win.destroy() |
| |
| def selectStart(self, event): |
| self.is_selecting = True |
| self.area.setStartPoint(event.x, event.y) |
| |
| |
| def changeSelectionArea(self, event): |
| if self.is_selecting: |
| self.area.updateEndPoint(event.x, event.y) |
| |
| |
| def selectDone(self, event): |
| |
| self.is_selecting = False |
| |
| if __name__ == '__main__': |
| this_main = MainWindow() |
| this_main.mainloop() |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~