Tkinter根据屏幕分辨率最大化适应屏幕

还不能够实现所有组件随分辨率自动变化

# 实现的是界面覆盖整个屏幕
from tkinter import *
import win32api, win32con

# 获取屏幕的分辨率
width = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)

# 设置UI界面
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任意区域截图的案例进行分析:

#! /usr/bin/env python
# ! -*- coding:utf-8 -*-
# ====#====#====#====
# HomePage:https://www.cnblogs.com/Qzzz/
# FileName: *.py
# ====#====#====#====
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):
        # self.ax.clear()
        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)):
            # print(num[i])
            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.win.tk.call('tk', 'scaling', scaling_factor)
        self.width = 960
        self.height = 813

        # 无边框,没有最小化最大化关闭这几个按钮,也无法拖动这个窗体,程序的窗体在Windows系统任务栏上也消失
        self.win.overrideredirect(True)
        self.win.attributes('-alpha', 0.1)

        self.is_selecting = False

        # 绑定按 Enter 确认, Esc 退出
        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)
        # print('Select', event)

    def changeSelectionArea(self, event):
        if self.is_selecting:
            self.area.updateEndPoint(event.x, event.y)
            # print(event)

    def selectDone(self, event):
        # self.area.updateEndPoint(event.x, event.y)
        self.is_selecting = False

if __name__ == '__main__':
    this_main = MainWindow()
    this_main.mainloop()

posted @ 2022-02-27 13:51  Mundane-_-  阅读(1050)  评论(0编辑  收藏  举报