python-3.xtkintermysql-connectorcustomtkinterpandastable

CustomTkinter grid placement


I'm trying to use customtkinter to display the contents of a MySQL database, but the placement of the table doesn't match the placement I've assigned in the grid. I'm pretty new to GUI Programming, so I'd love your help. Here's my code:

import customtkinter 
import mysql.connector
import pandas as pd
from pandastable import Table, TableModel

conn = mysql.connector.connect(user='root', password='0000', host='localhost', database='python', auth_plugin='mysql_native_password')
cursor = conn.cursor()

class MyFrame(customtkinter.CTkFrame):
    def __init__(self, master):
        super().__init__(master)
        self.header = customtkinter.CTkLabel(self, text="Dashboard", fg_color="transparent", font=("Product Sans",48))
        self.header.grid(row=0, column=0, sticky="w")
        command = "select * from fruits"
        table_width = 310
        table_height = 100
        df = pd.read_sql_query(command, conn)
        pt = Table(self, dataframe=df, width=table_width, height=table_height, showtoolbar=False, showstatusbar=False, showRowNumber=False)
        pt.grid(row=310, column=0)
        pt.show()
        pt.hideRowHeader()

class App(customtkinter.CTk):
    def __init__(self):
        super().__init__()

        self.title("my app")
        self.geometry("1280x720")
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self.frame = MyFrame(self)
        self.frame.grid(row=0, column=0, sticky='nw')
        self.frame.configure(width=1280, height=720)

        self.button = customtkinter.CTkButton(self, text="my button")
        self.button.grid(row=3, column=0, padx=10, pady=10, sticky="ew")

app = App()
app.mainloop()

Here's the output: Output

I want the Table to be below the title 'Dashboard', but it attaches to the side and the scrollbar keeps glitching as well.


Solution

  • Note that pandastable.Table has different parts which are put in the same parent frame (self, instance of MyFrame for your case). One of the part rowindexheader is put at row 0 and column 0 (same location of the label "Dashboard"). But it is hidden by calling pt.hideRowHeader() in your code, so you can see the label "Dashboard". If you remove the line pt.hideRowHeader(), the label "Dashboard" will be covered by the row header.

    You can move the label "Dashboard" out of MyFrame class and create it inside same parent of instance of MyFrame instead.

    Below is a simplified example based on yours:

    import customtkinter as ctk
    from pandastable import Table
    
    ctk.set_appearance_mode("dark")
    
    class MyFrame(ctk.CTkFrame):
        def __init__(self, master):
            super().__init__(master)
    
            table_width = 310
            table_height = 100
            pt = Table(self, width=table_width, height=table_height,
                       showtoolbar=False, showstatusbar=False, showRowNumber=False)
            pt.show()
            pt.hideRowHeader()
    
    root = ctk.CTk()
    root.geometry("400x300")
    
    header = ctk.CTkLabel(root, text="Dashboard", fg_color="transparent",
                          font=("Product Sans", 48))
    header.pack()
    
    frame = MyFrame(root)
    frame.pack(fill="both", expand=1)
    
    root.mainloop()
    

    And the output:

    enter image description here