全局变量未填写python3 ttk

时间:2016-01-24 16:24:26

标签: python

我正在尝试在Linux(Ubuntu 14.04LTS)系统上的python3中使用ttk.notebook来读取Blockquote`# - - 编码:utf-8 - - 来自实验的数据并执行几个曲线拟合此数据,以计算有限元计算所需的系数。 我已经在没有tkinter的情况下执行了这些曲线的实际计算。我现在正在设置用户界面。 一切正常,直到我想填充变量a作为全局变量,注意到导出到Ipython shell(使用spyder2)。变量:CreepData和path2以相同的方式全局化,在Ipython shell中是可见的。 我不确定我从组合框中提取值的方式或笔记本页面上的Entry字段选择单位并以预期方式运行工作。 请参阅以下代码:

""" Created on Sat Jan 16 18:56:16 2016

@author: peterk

Derived frpm a lot of posted examples """ import csv from copy import
deepcopy import numpy as np import matplotlib  import scipy import
matplotlib matplotlib.use("TkAgg") from
matplotlib.backends.backend_tkagg import
FigureCanvasTkAgg,NavigationToolbar2TkAgg from matplotlib.figure
import Figure from matplotlib import pyplot as plt from scipy import
stats from scipy.optimize import curve_fit from tkinter import *
import tkinter as tk import tkinter.font as tkFont import tkinter.ttk
as ttk from tkinter import filedialog path2="./creep.csv"

class CreepNotebook(ttk.Frame):

def __init__(self, isapp=True, name='notebookdemo'):
    ttk.Frame.__init__(self, name=name)
    self.pack(expand=True, fill="both")
    self.master.title('Creep fit')
    self.isapp = isapp
    self._create_widgets()
    self.master.minsize(1920,1000)
def _create_widgets(self):      
    self._create_main_panel()         
def _create_main_panel(self):
    mainPanel = ttk.Frame(self, name='demo')
    mainPanel.pack( expand=True, side="top",  fill="both")                 
    # create the notebook
    nb = ttk.Notebook(mainPanel, name='notebook')
    # extend bindings to top level window allowing
    #   CTRL+TAB - cycles thru tabs
    #   SHIFT+CTRL+TAB - previous tab
    #   ALT+K - select tab using mnemonic (K = underlined letter)
    nb.enable_traversal()
    nb.pack(fill="both", padx=2, pady=3,expand=True)
    self._create_readme_tab(nb)
    self._create_import_data_tab(nb)
    self._create_select_units_run_tab(nb)
    self._create_text_tab(nb)                      
def _create_readme_tab(self, nb):
    # frame explaining the app
    frame = ttk.Frame(nb, name='readMeFirst')

    # widgets to be displayed on 'Description' tab
    msg = ["Ttk is the new Tk themed widget set. One of the widgets ",
           "it includes is the notebook widget, which provides a set ",
           "of tabs that allow the selection of a group of panels, ",
           "each with distinct content. They are a feature of many ",
           "modern user interfaces. Not only can the tabs be selected ",
           "with the mouse, but they can also be switched between ",
           "using Ctrl+Tab when the notebook page heading itself is ",
           "selected. Note that the second tab is disabled, and cannot "
           "be selected."
           " aaaaaaaaaaaaaaa      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
           "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
           "ccccccccccccccccccccccccccccccccccccccccccccccccccccccc",            

           "dddddd",               
            "eeeee",              
           "f",              
           "a",               
           "b",               
           "c",               
           "d",               
           "e",               
           "f",               
           "g",               
           "h",               
          " here is text too"]

    lbl = ttk.Label(frame, wraplength='4i', justify=tk.LEFT, anchor=tk.CENTER,
                    text=''.join(msg))
    neatVar = tk.StringVar()
    btn = ttk.Button(frame, text='Neat!', underline=0,
                     command=lambda v=neatVar: self._say_neat(v))
    neat = ttk.Label(frame, textvariable=neatVar, name='neat')

    # position and set resize behaviour
    lbl.grid(row=0, column=0, columnspan=2, sticky='new', pady=5)
    btn.grid(row=1, column=0, pady=(2,4))
    neat.grid(row=1, column=1,  pady=(2,4))
    frame.rowconfigure(1, weight=1)
    frame.columnconfigure((0,1), weight=1, uniform=1)

    # bind for button short-cut key
    # (must be bound to topplevel window)
    self.winfo_toplevel().bind('<Alt-n>', lambda e, v=neatVar: self._say_neat(v))

    # add to notebook (underline = index for short-cut character)
    nb.add(frame, text='ReadMeFirst', underline=0, padding=2)

def _say_neat(self, v):
    v.set('Yeah, I know...')
    self.update()
    self.after(500, v.set(''))

#        return path2
# =============================================================================
def _create_import_data_tab(self, nb):
    # Populate the second pane. 
    frame = ttk.Frame(nb, name="import data")
    global l
    global k
    global sigma
    global creepData
    global filen
    global path2
    butn=ttk.Button(frame, text='select csv file', command=self.askopenfilename2)
    butn.pack(side="top")
    self.file_opt = options = {}
    options['defaultextension'] = '.csv'
    options['filetypes'] =[('csv files', '.csv'),('all files', '.*')]
    options['initialdir'] = '.'
    options['initialfile'] = 'creep2.csv'
    options['parent'] = nb
    options['title'] = 'Select csv file'
    global creepData
    print("path2 in _create_import_data_tab")
    print (path2)
    nb.add(frame, text='Import data', underline=0)
def askopenfilename2(self):
    global path2
    global creepData
    path2 = filedialog.askopenfilename(**self.file_opt)
    print("path2 in askopenfilename2")
    print(path2)    
    creepReader=csv.reader(open(path2, newline=""), delimiter=',')
    creepData=list(creepReader)
#enter code here
========================================
def _create_text_tab(self, nb):
    # populate the third frame with a text widget
    frame = ttk.Frame(nb)

    txt = tk.Text(frame,  width=40, height=10)
    vscroll = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=txt.yview)
    txt['yscroll'] = vscroll.set
    vscroll.pack(side=tk.RIGHT)
#   txt.pack(tk.fill=BOTH, tk.expand=True)
    txt.pack() #        btn2l.pack(side="top", pady=5)
#   btn2.pack(side="top", pady=2)
#   w.pack(side="top", pady=2)
#   neatVar = tk.StringVar()
#        btn = ttk.Button(frame, text='Neat!', underline=0,
#                         command=lambda v=neatVar: self._say_neat(v))
#        neat = ttk.Label(frame, textvariable=neatVar, name='neat')
#    def _say_neat(self, v):
#        v.set('Yeah, I know...')
#        self.update()
#        self.after(500, v.set(''))
    # add to notebook (underline = index for short-cut character)
    nb.add(frame, text='Text Editor', underline=0)
#============================================================
def _create_select_units_run_tab(self, nb):
    # select units and perform the calculation
    frame = ttk.Frame(nb, name="select units and calculate")
    global l
    global k
    global sigma
    global creepData
    global a
    a=tk.StringVar()
    frame.grid(column=0, row=0, rowspan=12, columnspan=5,sticky=(N,S,E,W))

    units = ('m,kg,s', 'mm,Mg,s', 'mm,kg,ms')
    a=tk.StringVar()
    cbl0 = ttk.Label(frame, text='Select or fill in the required fields and push the run button')
    cbl1 = ttk.Label(frame, text='Select units used in your FE-prgram')
    cb1 = ttk.Combobox(frame, value=units, state='readonly')
#        cbl1.pack(side="top")
#        cb1.pack(side="top")
    time_units=('hrs', 's','ms')
    cbl2=ttk.Label(frame, text='Select time units used in the csv file')
    cb2 = ttk.Combobox(frame, value=time_units, state='readonly')
#        cbl2.pack(side="top")
#        cb2.pack(side="top") 
    strain_units=('strain [%]', 'strain [-]','CreepModulus [MPa]')
    cbl3=ttk.Label(frame, text='Select strain or modulus  units used in the csv file')
    cb3 = ttk.Combobox(frame, value=strain_units, state='readonly')
#        cbl3.pack(side="top")
#        cb3.pack(side="top")
    yml=ttk.Label(frame, text=' Input Anisotropic Youngs Modulus in MPa')
    ym=Entry(frame)
#        yml.pack(side="top")
#        ym.pack(side="top")
    isfl=ttk.Label(frame, text='Input Isotropic factor')
    isf=Entry(frame)
#        isfl.pack(side="top")
#        isf.pack(side="top")
    run1Var = tk.StringVar()
    btn2 = ttk.Button(frame, text='Run', underline=0,
                     command=lambda w=run1Var: self._run1(w))
    btn2l = ttk.Label(frame, textvariable=run1Var, name='run1')
    cbl0.grid(column=0, row=0, sticky=W, pady=100)
    cbl1.grid(column=6, row=1, sticky=W, pady=25)
    cb1.grid(column=6, row=2, sticky=W, pady=2)
    cbl2.grid(column=6, row=3, sticky=W, pady=25)
    cb2.grid(column=6, row=4, sticky=W, pady=2)
    cbl3.grid(column=6, row=5, sticky=W, pady=25)
    cb3.grid(column=6, row=6, sticky=W, pady=2)
    yml.grid(column=6, row=7, sticky=W, pady=25)
    ym.grid(column=6, row=8,  sticky=W ,pady=2)
    isfl.grid(column=6, row=9, sticky=W, pady=25)
    isf.grid(column=6, row=10, sticky=W, pady=2)        
    btn2l.grid(column=6, row=11, sticky=W, pady=25)
    btn2.grid(column=6, row=12, sticky=W, pady=2)        
    nb.add(frame, text='Select data and run', underline=0, padding=2)
    a=cb1.get()
    print(a)
    print(cb1.get())
    yms=ym.get()
    isfs=isf.get()                  

def _run1(self, w):
#        global CreepData
#        global creepDat
#        creepDat=deepcopy(creepData)
    w.set('CreepData is copied')
    self.update()
    self.after(500, w.set(''))

#===================================================================
if __name__ == '__main__':
    CreepNotebook().mainloop()`
     

如果需要,我可以在我的repro上传csv.files,但我认为不需要回答这个问题。 run1函数将用于拟合数据曲线并返回执行计算的消息。

1 个答案:

答案 0 :(得分:0)

已更改 - 抱歉,我最初没有理解您的问题,这可能会更有帮助:

首先,我建议您仔细研究这两个方面:

when to use global statement

Share variables between methods

第二,您在_create_select_units_run_tab中创建输入条目,然后执行:

def _create_select_units_run_tab:
    ...
    a = cb1.get()
    ...

这将在创建后立即获取内容,甚至在.mainloop()被调用之前,因此它绝对总是一个空字符串,以便稍后在_run1中获取内容,您需要跟踪而是改为:

def _create_select_units_run_tab:
    ...
    self.input_fields = [cb1,cb2,cb3,ym,isf]
    #this will give all other methods access to the input fields

#then to get them back you can use this:
def get_inputs(self):
    return [entry.get() for entry in self.input_fields]

#then in run you can get the data in the fields
def _run1(self, w):
    inp_data = self.get_inputs()
    print(inp_data)
    if "" in inp_data:
        w.set("you need to fill everthing in first!")
    else:
        w.set(str(inp_data))
    ...

在测试代码时,我取消了因path2 == ""而导致错误的文件对话框窗口,因此您可能需要检查:

def askopenfilename2(self):
    ...
    if path2 is not "":
        creepReader=csv.reader(open(path2, newline=""), delimiter=',')
        creepData = list(creepReader)
    #else:
    #    creepData = None # or just leave it as the last used value?
    ...

更不用说open()永远不会关闭(Input and Output Python documentation):

在处理文件对象时,最好使用with关键字。这样做的好处是,即使在路上引发异常,文件也会在套件完成后正确关闭。它也比编写等效的`try-finally`块短得多:     
    with open('workfile', 'r') as f:
    ...     read_data = f.read()
    >>> f.closed
    True

所以你可能也希望实现它:

    with open(path2, newline="") as file_obj:
        creepReader=csv.reader(file_obj, delimiter=',')

最后,我想提请注意:

self.after(500,w.set('')
立即调用

w.set('')并使用None中的返回值self.after,而是使用您需要执行此操作的参数调用w.set

self.after(500,w.set,'')

然后tkinter会在500ms后调用它,转发它在after

中收到的任何额外参数

我错过了您的代码可能存在的其他问题,但我希望这会有所帮助。