简体   繁体   English

无法让 tkinter 网格按我的意愿布局我的 GUI

[英]Cannot get tkinter grid to layout my GUI as I want

sorry for the simple question.对不起这个简单的问题。 Relatively new to python and especially Object Oriented and Class systems.相对较新的 python 尤其是 Object 面向和 Class 系统。 Basically, I want my GUI to have a couple of rows across the top of the window (across full width).基本上,我希望我的 GUI 在 window 的顶部有几行(全宽)。 Beneath, I want 4 equal sized columns.下面,我想要 4 个大小相等的列。 I don't want this to impact my plots (on a different page).我不希望这影响我的情节(在不同的页面上)。 Any help is much appreciated.任何帮助深表感谢。 I cannot workout how to use tkinter to get this to work.我无法锻炼如何使用 tkinter 让它工作。

Thanks谢谢

__author__ = "dev"

# https://pythonprogramming.net/object-oriented-programming-crash-course-tkinter/?completed=/tkinter-depth-tutorial-making-actual-program/
import tkinter as tk
from tkinter import ttk
import yfinance as yf
import datetime as dt
import matplotlib
from matplotlib import style
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib import pyplot as plt

import matplotlib.dates as mdates

LargeFont = ("Verdana", 16)
style.use("ggplot")

def yfinance_get(index):
    tkr = yf.Ticker(index)

    today = dt.datetime.today().isoformat()
    m_ago = dt.datetime.today() - dt.timedelta(days=30)

    h_px = tkr.history(period="1d", start=m_ago, end=today[:10])

    return h_px


class DailySumm(tk.Tk):
    def __init__(self, *args, **kwargs):  # initialise - runs as soon as the class is called
        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)  # frame creates the window of our GUI
        container.pack(side="top", expand=True)  # pack is similar to grid, but less accurate
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        # creates an empty dictionary called named self.frames, this will hold the diff "pages" in the Gui

        for f in (StartPage, Equities):  # for each page defined, this tuple needs to be updated to include
            # this loop will add the pages to the self.frames dict
            frame = f(container, self)
            self.frames[f] = frame  # enters a new entry into the dictionary, the StartPage page
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)  # this calls the show_frame method with cont = StartPage

    def show_frame(self, cont):
        frame = self.frames[cont]  # cont = dict key to frames (dict)
        frame.tkraise()  # this raises the "frame" to the front of the window (i.e. shows it to the user)


class StartPage(tk.Frame):  # this creates the StartPage page which inherits the tk.Frame functionality (ie imports)
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)  # parent is the parent class, in this case DailySumm

        label = tk.Label(self, text="News and Market Data", font=LargeFont).grid(row=0, column=0, columnspan=4)
        label2 = tk.Label(self, text="Equities", font=LargeFont).grid(row=1, column=0, padx=10)
        label3 = tk.Label(self, text="Credit", font=LargeFont).grid(row=1, column=1, padx=10)
        label4 = tk.Label(self, text="Currencies", font=LargeFont).grid(row=1, column=2, padx=10)
        label5 = tk.Label(self, text="Commodities", font=LargeFont).grid(row=1, column=3, padx=10)

        button_equ = ttk.Button(self, text="Equities",
                                command=lambda: controller.show_frame(Equities)).grid(row=2, column=0)
        # lambda stops the function being called on inception, only when the button is pressed


class Equities(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Equities", font=LargeFont)
        label.pack(pady=10, padx=10)

        button_home = ttk.Button(self, text="Back to Home",
                                 command=lambda: controller.show_frame(StartPage))
        button_home.pack()

        index = [['FTSE 100', '^FTSE'], ['S&P 500', '^GSPC'], ["Nikkei 225", "^N225"], ["MSCI EM", "EEM"]]
        fig = Figure(dpi=100)

        for i in range(0, 3+1):
            ax = fig.add_subplot(2, 2, i+1)
            plot_data = yfinance_get(index[i][1])
            ax.plot(plot_data['Close'], color='r', label=index[i][0])
            ax.grid(which="major", color='k', linestyle='-.', linewidth=0.3)
            ax.legend(loc=2)
            ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.MONDAY))
            ax.xaxis.set_major_formatter(mdates.DateFormatter("%d-%m"))


        canvas = FigureCanvasTkAgg(fig, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)


app = DailySumm()
app.geometry("2560x1600")
app.mainloop()

One way to do this is to create a frame for the rows at the top, and another frame to hold the four columns below.一种方法是为顶部的行创建一个框架,并为下面的四列创建另一个框架。 You can use pack to add these frames to the window, and use grid in the lower frame to manage the columns.您可以使用pack将这些框架添加到 window,并使用下部框架中的grid来管理列。 To get the columns to be the same size you can use the uniform option for each column.要使列的大小相同,您可以对每列使用uniform选项。

Here's an example of the technique:这是该技术的一个示例:

import tkinter as tk

root = tk.Tk()

top_frame = tk.Frame(bd=1, relief="raised", height=50)
bottom_frame = tk.Frame(bd=1, relief="raised")

top_frame.pack(side="top", fill="x")
bottom_frame.pack(side="bottom", fill="both", expand=True)

# add labels to the columns so that we can visualize the columns
labels = (
    tk.Label(bottom_frame, bd=1, relief="raised", text="Column 1", height=8, width=10),
    tk.Label(bottom_frame, bd=1, relief="raised", text="Column 2", height=8, width=10),
    tk.Label(bottom_frame, bd=1, relief="raised", text="Column 3", height=8, width=10),
    tk.Label(bottom_frame, bd=1, relief="raised", text="Column 4", height=8, width=10)
)

# add the labels to the columns.
labels[0].grid(row=0, column=0, sticky="nsew", ipadx=4)
labels[1].grid(row=0, column=1, sticky="nsew", ipadx=4)
labels[2].grid(row=0, column=2, sticky="nsew", ipadx=4)
labels[3].grid(row=0, column=3, sticky="nsew", ipadx=4)

# allocate all extra horizontal space to each column evenly
# the critical piece is both the weight and uniform options
bottom_frame.grid_columnconfigure(0, weight=1, uniform="column")
bottom_frame.grid_columnconfigure(1, weight=1, uniform="column")
bottom_frame.grid_columnconfigure(2, weight=1, uniform="column")
bottom_frame.grid_columnconfigure(3, weight=1, uniform="column")

# allocate all extra vertical space to row 0
bottom_frame.grid_rowconfigure(0, weight=1)

root.mainloop()

截屏

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM