【问题标题】:Put two window results to a window with two tabs将两个窗口结果放到具有两个选项卡的窗口中
【发布时间】:2020-01-04 17:07:56
【问题描述】:

开始页面上有两个按钮。按钮显示两种不同的结果。弹出两个窗口来查看结果似乎太拥挤了。我希望通过在第一个窗口中单击一个按钮,将结果显示在一个带有两个选项卡的窗口中(两个选项卡指的是来自按钮的两个结果)。我该怎么做?

下面的代码是可执行的。

import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

all_figures1 = []
selected_figure1 = 0 
all_figures2 = []
selected_figure2 = 0 


class MyClass1():

    def __init__(self):

        self.sheets = [[1,2,3], [3,1,2], [1,5,1]]
        self.W = 2
        self.L = 5


    def plot_sheet(self, data):
        """plot single figure"""

        fig, ax = plt.subplots(1)

        ax.set_xlim([0, self.W]) 
        ax.set_ylim([0, self.L])

        ax.plot(data)

        return fig

    def generate_all_figures(self):
        """create all figures and keep them on list"""
        global all_figures

        for data in self.sheets:
            fig = self.plot_sheet(data)
            all_figures1.append(fig)


class MyClass2():

    def __init__(self):

        self.sheets = [[3,2,1], [2,5,3], [5,1,5]]
        self.W = 2
        self.L = 5


    def plot_sheet(self, data):
        """plot single figure"""

        fig, ax = plt.subplots(1)

        ax.set_xlim([0, self.W]) 
        ax.set_ylim([0, self.L])

        ax.plot(data)

        return fig

    def generate_all_figures(self):
        """create all figures and keep them on list"""
        global all_figures

        for data in self.sheets:
            fig = self.plot_sheet(data)
            all_figures2.append(fig)


dataPlot1 = None  
dataPlot2 = None  

def on_window1():

    def show_figure(number):
        global dataPlot1

        current_num = str(number+1)
        total_num = str(len(all_figures1))



        counter = tk.Label(top, text = current_num + "/" + total_num)
        counter.grid(row=4,column=0)



        # remove old canvas
        if dataPlot1 is not None: # at start there is no canvas to destroy
            dataPlot1.get_tk_widget().destroy()

        # get figure from list
        one_figure = all_figures1[number]

        # display canvas with figuere
        dataPlot = FigureCanvasTkAgg(one_figure, master=top)
        dataPlot.draw()
        dataPlot.get_tk_widget().grid(row=0, column=0)

        toolbar_frame = tk.Frame(top)
        toolbar_frame.grid(row=1,column=0)
        toolbar = NavigationToolbar2Tk(dataPlot, toolbar_frame)
        toolbar.update()

    def on_prev():
        global selected_figure1

        # get number of previous figure
        selected_figure1 -= 1
        if selected_figure1 < 0:
            selected_figure1 = len(all_figures1)-1

        show_figure(selected_figure1)

    def on_next():
        global selected_figure1

        # get number of next figure
        selected_figure1 += 1
        if selected_figure1 > len(all_figures1)-1:
            selected_figure1 = 0

        show_figure(selected_figure1)

    top = tk.Toplevel()
    top.wm_geometry("794x370")
    top.title('Optimized Map 1')

    selected_figure1 = 0
    dataPlot = None # default value for `show_figure`
    show_figure(selected_figure1)

    frame = tk.Frame(top)
    frame.grid(row=3, column=0)

    b1 = tk.Button(frame, text="<<", command=on_prev)
    b1.grid(row=2, column=0)

    b2 = tk.Button(frame, text=">>", command=on_next)
    b2.grid(row=2, column=1)



def on_window2():

    def show_figure(number):
        global dataPlot2

        current_num = str(number+1)
        total_num = str(len(all_figures2))


        counter = tk.Label(top, text = current_num + "/" + total_num)
        counter.grid(row=4,column=0)



        # remove old canvas
        if dataPlot2 is not None: # at start there is no canvas to destroy
            dataPlot2.get_tk_widget().destroy()

        # get figure from list
        one_figure = all_figures2[number]

        # display canvas with figuere
        dataPlot = FigureCanvasTkAgg(one_figure, master=top)
        dataPlot.draw()
        dataPlot.get_tk_widget().grid(row=0, column=0)

        toolbar_frame = tk.Frame(top)
        toolbar_frame.grid(row=1,column=0)
        toolbar = NavigationToolbar2Tk(dataPlot, toolbar_frame)
        toolbar.update()

    def on_prev():
        global selected_figure2

        # get number of previous figure
        selected_figure2 -= 1
        if selected_figure2 < 0:
            selected_figure2 = len(all_figures2)-1

        show_figure(selected_figure2)

    def on_next():
        global selected_figure2

        # get number of next figure
        selected_figure2 += 1
        if selected_figure2 > len(all_figures2)-1:
            selected_figure2 = 0

        show_figure(selected_figure2)

    top = tk.Toplevel()
    top.wm_geometry("794x370")
    top.title('Optimized Map2')

    selected_figure2 = 0
    dataPlot = None # default value for `show_figure`
    show_figure(selected_figure2)

    frame = tk.Frame(top)
    frame.grid(row=3, column=0)

    b1 = tk.Button(frame, text="<<", command=on_prev)
    b1.grid(row=2, column=0)

    b2 = tk.Button(frame, text=">>", command=on_next)
    b2.grid(row=2, column=1)

window = tk.Tk()

mc1 = MyClass1()
mc1.generate_all_figures()

mc2 = MyClass2()
mc2.generate_all_figures()

b1 = tk.Button(window, text="Next", command=on_window1)
b1.grid(row=0, column=0)

b2 = tk.Button(window, text="Next", command=on_window2)
b2.grid(row=1, column=0)

window.mainloop()

【问题讨论】:

    标签: python python-3.x tkinter


    【解决方案1】:

    您应该按照以下方式添加一个函数:

    def switch_tabs(clicked):
        global active
        tabs[active].grid_forget()
        tabs[clicked].grid()
        active = clicked
    

    其中tabs 可以是帧键的列表或字典,active 是表示活动选项卡的全局变量,clicked 是表示已单击选项卡的键。框架本身需要一个共同的父级——比如主窗口。 Here's some documentation grid_forget

    然后,当您创建按钮时,您可以将此函数包装在直接指向其选项卡的 lambda 中。您可能希望将按钮本身与两个选项卡的公共父级放在同一框架上。

    b1 = tk.Button(window, text="<<", command=lambda: switch_tabs(tab1))
    

    在这种情况下,tab1 可以是一个字符串或整数,它与您想要通过按下按钮切换到的选项卡相关联。例如,如果您使用列表来存储帧,tab1 可能是 0 - 如果您使用字典,它可能是 'tab1'

    在这里,我还使用了lambda expression 作为定义新函数的快速简单的方法。我可以很容易地写出类似的东西

    def switch_to_tab1():
        switch_tabs(tab1)
    b1 = tk.Button(window, text="<<", command=switch_to_tab1)
    

    【讨论】:

    • 我无法弄清楚 b1 部分。你能解释一下吗?
    • @devinxxxd 我已经编辑了我的答案,希望能提供更清晰的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 2013-11-04
    • 2013-09-18
    • 2023-03-24
    相关资源
    最近更新 更多