【问题标题】:How do you use Toplevel() to detach/open a new graph window in Tkinter?你如何使用 Toplevel() 在 Tkinter 中分离/打开一个新的图形窗口?
【发布时间】:2020-07-30 17:45:10
【问题描述】:

我是 Tkinter 编程的新手,在了解 Tkinter 如何处理类、函数等时可以使用一些帮助。

我正在尝试通过图形窗口中的按钮“分离”图形窗口。我需要能够打开类 GraphPage_cpu -> 查看带有绘图的页面,然后按“测试”按钮并让它打开一个带有 cpu 测量绘图的新窗口。

另外,我必须给用户“j_4321”一个巨大的荣誉。在弄清楚如何绘制 CPU 度量方面,他真的帮了我很多!

这是尝试分离(或在新窗口中“重新打开”图形)的主要功能:

def detach_graph(self):
        self.detach_graph = Toplevel(self.parent)
        self.app = GraphPage_cpu(self.detach_graph)

错误信息:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "<ipython-input-12-f73649f067eb>", line 124, in new_window
    self.newWindow = Toplevel(self.parent)
AttributeError: 'GraphPage_cpu' object has no attribute 'parent'

完整代码:

import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from tkinter import Toplevel
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showinfo, showwarning, askquestion
from tkinter import OptionMenu
from tkinter import StringVar

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
from matplotlib import style
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.dates as mdates
from psutil import cpu_percent
from psutil import virtual_memory
from datetime import datetime, timedelta

from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans
import sklearn.cluster as cluster
import scipy.spatial.distance as sdist
from sklearn.ensemble import IsolationForest

import pandas as pd
import numpy as np
import seaborn as sn

from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler

RANDOM_STATE = 42 #used to help randomly select the data points
low_memory=False
LARGE_FONT= ("Verdana", 12)
style.use("ggplot")

f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)


class Analyticsapp(tk.Tk):

    def __init__(self, *args, **kwargs):
        
        tk.Tk.__init__(self, *args, **kwargs)
        
        #tk.Tk.iconbitmap(self, default="iconimage_kmeans.ico") #Icon for program
        tk.Tk.wm_title(self, "Advanched analytics")
        
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        
        self.frames = {} 
        
        for F in (StartPage, GraphPage_cpu):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()
        
class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text=
                         "Advanched analytics", font=LARGE_FONT)
        label.pack(pady=10, padx=10)
        
        button3 = ttk.Button(self, text="CPU Usage", 
                            command=lambda: controller.show_frame(GraphPage_cpu))
        button3.pack(fill='x')

class GraphPage_cpu(tk.Frame):

    def __init__(self, parent, controller, nb_points=360):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="CPU Usage", font=LARGE_FONT)
        label.pack(pady=10, padx=10, side='top')

        # matplotlib figure
        self.figure = Figure(figsize=(5, 5), dpi=100)
        self.ax = self.figure.add_subplot(111)
        # format the x-axis to show the time
        myFmt = mdates.DateFormatter("%H:%M:%S")
        self.ax.xaxis.set_major_formatter(myFmt)
        # initial x and y data
        dateTimeObj = datetime.now() + timedelta(seconds=-nb_points)
        self.x_data = [dateTimeObj + timedelta(seconds=i) for i in range(nb_points)]
        self.y_data = [0 for i in range(nb_points)]
        # create the plot
        self.plot = self.ax.plot(self.x_data, self.y_data, label='CPU')[0]
        self.ax.set_ylim(0, 100)
        self.ax.set_xlim(self.x_data[0], self.x_data[-1])

        self.canvas = FigureCanvasTkAgg(self.figure, self)

        toolbar = NavigationToolbar2Tk(self.canvas, self)
        toolbar.update()

        button1 = ttk.Button(self, text="Back",
                             command=lambda: controller.show_frame(StartPage))
        button1.pack(side='bottom')
        
        button2 = ttk.Button(self, text="Test",
                             command=self.new_window)
        button2.pack(side='bottom')
        
        self.canvas.get_tk_widget().pack(side='top', fill=tk.BOTH, expand=True)
        self.animate_cpu()
        
    def detach_graph(self):
        self.detach_graph = Toplevel(self.parent)
        self.app = GraphPage_cpu(self.detach_graph)

    def animate_cpu(self):
        # append new data point to the x and y data
        self.x_data.append(datetime.now())
        self.y_data.append(cpu_percent())
        # remove oldest data point
        self.x_data = self.x_data[1:]
        self.y_data = self.y_data[1:]
        #  update plot data
        self.plot.set_xdata(self.x_data)
        self.plot.set_ydata(self.y_data)
        self.ax.set_xlim(self.x_data[0], self.x_data[-1])
        self.canvas.draw_idle()  # redraw plot
        self.after(1000, self.animate_cpu)  # repeat after 1s
        
app = Analyticsapp()
app.geometry('500x400')
app.mainloop()


【问题讨论】:

  • self.parent = parent 添加到GraphPage_cpu.__init__() 以便属性存在。
  • 在“GraphPage_cpu.__init__()”下的“tk.Frame.__init__(self, parent)”下添加“self.parent = parent”时出现错误; “TypeError:__init__() 缺少 1 个必需的位置参数:‘控制器’”
  • GraphPage_cpu.__init__() 方法的开头附近添加self.parent = parent 不会导致该错误——不要更改tk.Frame.__init__(self, parent) 调用(或其他任何内容)。

标签: python function class tkinter


【解决方案1】:

如果我了解该问题(由于依赖关系而无法运行),
您需要获取某些小部件的父级。
tkinter 使用'master',而不是'parent',所以试试:

self.newWindow = Toplevel(self.master)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 2022-01-19
    • 1970-01-01
    相关资源
    最近更新 更多