TomSchimansky / CustomTkinter

A modern and customizable python UI-library based on Tkinter
MIT License
11.6k stars 1.09k forks source link

Buggy UI #1952

Open EpicCodeWizard opened 1 year ago

EpicCodeWizard commented 1 year ago

I've built a small CustomTkinter app. It provides a way to scan a QR code. However, the interface is a bit slow (see below). This is caused by the window resizing. On resize, the remaining space in the window is calculated. Then, the QR code is sized up to take up the remaining space. This way, all the screen space is used. However, this causes a constant recalculation and the UI becomes buggy on resize. Is there any way to instantly calculate the space left?

https://github.com/TomSchimansky/CustomTkinter/assets/83260377/58fa0980-8484-4204-bd02-4c408cbf24d7

Current Code: https://github.com/EpicCodeWizard/CustomTkinter-App

EDIT: I've also tried adding a split view, where the user can drag a middle bar left and right to resize either section, but that is worse. The UI doesn't scale as fast as the user drags the middle bar. I've included a video below:

https://github.com/TomSchimansky/CustomTkinter/assets/83260377/c20c7a73-6d74-4515-a86a-f47ebc767e5d

Originally posted by @EpicCodeWizard in https://github.com/TomSchimansky/CustomTkinter/discussions/1919

TomSchimansky commented 1 year ago

How do you calculate the image size and why does it update multiple times?

EpicCodeWizard commented 1 year ago

The following code calculates image size on the window resize:

    def dynamic_resize(self, event) -> None:
        """
        Dynamically resizes the image to fill up the space of the button.
        """

        self.scale = ctk.ScalingTracker.get_window_dpi_scaling(self.master)

        side = min(event.width, event.height) / self.scale
        if not self.raw_image is None:
            self.image = ctk.CTkImage(light_image = self.raw_image,
                                    size = (side, side)
                                    )
        self.configure(True, image = self.image)

This app is meant to display the qr code above the text boxes. I need the qr code to take up the remaining space on the screen, no matter the screen size. This way, the entirety of the window's height is filled. However, the calculation makes the UI buggy. Do you have any suggestions on how speed can be increased or any other implementations of making the image fill the rest of the space? The app uses a grid system, and weight is emphasized on the qr code's row, but that has seemingly no effect.

yqushair commented 1 year ago

When you add the QR code image to the grid using the grid() method, you can pass in the argument sticky='nsew' to make it so that the image clings to the edges of its cell on all sides. You'll probably also make use of rowconfigure() and columnconfigure(), which you would call on the parent frame that contains the QR code. Specifically, you would pass in the relevant row/column number and the parameter weight=1. The exact strategy would depend on your implementation, but presumably it would be something like:

QRcode.grid(row=0, column=0,..., sticky='nsew')
frameContainingQRCode.rowconfigure(0, weight=1)
frameContainingQRCode.columnconfigure(0, weight=1)

Using some combination of those functions, you should be able to get the QR code to resize automatically without having to write your own dynamic resizing function. Hope this is helpful!