You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让打包为exe的Tkinter应用适配不同分辨率设备及远程桌面

Tkinter应用远程桌面适配解决方案

问题描述

我编写的Tkinter应用本地运行正常,经PyInstaller打包为exe后,在远程桌面环境打开失败。推测原因是使用.place()布局时硬编码了x、y坐标,无法适配不同设备的分辨率;但canvas.get_tk_widget().place_forget()清除图表的方式便捷有效,且已知同一程序中不能混用grid与place布局,希望找到既能保留便捷的图表清除方式,又能让exe在任意电脑正常运行的方法。

解决方案

  • 工具栏按钮替换布局:将工具栏中用place(x=xxx)定位的按钮改用pack(side=RIGHT),无需硬编码坐标即可实现右侧对齐,适配不同窗口宽度
  • 图表区域改用grid布局:给页面框架配置网格权重,将图表控件放入grid布局,清除时用grid_forget()替代place_forget(),既保留便捷性,又实现自适应
  • 窗口动态适配屏幕:移除固定窗口尺寸,改为让窗口自适应内容或按屏幕比例调整,避免因屏幕分辨率差异导致显示异常
  • 移除硬编码坐标:所有控件布局尽量使用相对位置、权重分配或对齐方式,彻底摆脱固定坐标的限制

修改后的代码示例

import tkinter as tk
from tkinter import ttk
from tkmacosx import Button
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np

plt.close("all")

class Window(tk.Tk):
    def __init__(self,*args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(StartPage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent, bg='#192232') 
        toolbar0 = tk.Frame(self, bg="#393951")
        toolbar0.pack(side=tk.TOP, fill=tk.X)
        
        # 左侧标题
        label = ttk.Label(toolbar0, text="OLE Analyser")
        label.pack(side=tk.LEFT, pady=7, padx=10)
        
        # 右侧按钮,用pack(side=RIGHT)替代固定坐标place
        button = Button(toolbar0, text="Analysis", command=lambda: controller.show_frame(PageOne))
        button.pack(side=tk.RIGHT, padx=10, pady=6)   

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent, bg='#192232')
        toolbar1 = tk.Frame(self, bg="#393951")
        toolbar1.pack(side=tk.TOP, fill=tk.X)
        
        # 左侧留空,右侧按钮用pack(side=RIGHT)
        button2 = Button(toolbar1, text="Comparison", command=lambda: controller.show_frame(PageTwo))
        button2.pack(side=tk.RIGHT, padx=10, pady=6)
        button1 = Button(toolbar1, text="Home", command=lambda: controller.show_frame(StartPage))
        button1.pack(side=tk.RIGHT, padx=10, pady=6)

        # 配置页面网格布局:1行3列,中间列放图表,左右列留空自适应
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=0)
        self.grid_columnconfigure(2, weight=1)
        
        fig, ax = plt.subplots(figsize=(9.05,6.43))
        canvas1 = FigureCanvasTkAgg(fig, self) 
        
        x1 = np.arange(1,100,2)
        y1 = x1**2 
        ax.plot(x1,y1)
        canvas1.draw()
        # 图表放在中间列,sticky让它居中,padx/pady控制间距
        self.canvas_widget = canvas1.get_tk_widget()
        self.canvas_widget.grid(row=1, column=1, padx=20, pady=20, sticky="nsew")
        
        def clear_graph():
            # 用grid_forget替代place_forget,同样便捷
            self.canvas_widget.grid_forget() 
            
        # 清除按钮放在底部中间,用grid布局
        clear_btn = Button(self, text="Clear Graph", command=clear_graph)
        clear_btn.grid(row=2, column=1, pady=20)        
   
class PageTwo(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent, bg='#192232')
        toolbar2 = tk.Frame(self, bg="#393951")
        toolbar2.pack(side=tk.TOP, fill=tk.X)
 
if __name__ == "__main__":
    app = Window()             
    # 窗口按屏幕80%比例设置,适配不同分辨率
    screen_w = app.winfo_screenwidth()
    screen_h = app.winfo_screenheight()
    app.geometry(f"{int(screen_w*0.8)}x{int(screen_h*0.8)}")
    # 让窗口居中显示
    app.update_idletasks()
    x = (screen_w - app.winfo_width()) // 2
    y = (screen_h - app.winfo_height()) // 2
    app.geometry(f"+{x}+{y}")
    app.mainloop()

内容的提问来源于stack exchange,提问作者Chat0924

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:31:02