python tkinter窗口程序设计实战(四)--创建子页面(点击按钮给子页面传参数)及子页面Entry获取不到值的问题

发布于:2022-12-02 ⋅ 阅读:(976) ⋅ 点赞:(0)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在做程序时需要创建一个子页面来继续进行别的操作,有时会遇见创建不了,或者创建的不满意,以及创建出的子页面Entry获取不到输入值的情况,接下来我将介绍我遇见此类问题时尝试的解决方案。

一、创建子页面

1.先看效果图

这是我的其中一个页面,全部使用for循环做出的按钮,现在当我点击按钮时我需要程序创建一个子页面进行输入操作。

这是我所创建的子页面。 

 2.看代码

这是该页面主页面的代码,最后一个函数create2是创建子页面的代码。

在create2中使用with写入log.txt文件,是我想到的主页面给子页面传参数的取巧办法,通过点击按钮得到该按钮所代表的文件名,将文件名覆盖写入log.txt中,子页面在使用按钮所代表值时在txt中读取即可。

from tkinter import *
import os
import math
from mainPage import *
import tkinter
import random
from word import *


class danShua(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.root.geometry('%dx%d' % (600, 400))  # 设置窗口大小
        self.input = StringVar()  # 创建变量保存输入及输入内容的数据类型
        self.temp = StringVar()
        self.word = []
        self.flag = 1
        self.creatPage()

    def creatPage(self):
        path = './ciBen'
        temp = os.listdir(path)
        temp = [i.split('.')[0] for i in temp]
        num = 0
        # 每行三列,使用math库中的ceil方法向上取整
        # 外层控制行数,内层控制列数
        # if判断是否到达最后一行,当到达最后一行时做出应有的反应

        Label(self, text='请选择词本').grid(row=0, column=0, columnspan=3, stick=S)
        for i in range(1, math.ceil(len(temp) / 3) + 1):
            if len(temp) % 3 != 0 and i == math.ceil(len(temp) / 3):
                # lambda作用是保证button在不点击的情况下不调用函数
                Button(self, width=13, text=temp[num], command=lambda: self.create2(temp[num])).grid(row=i, column=0,
                                                                                                     stick=W, pady=5)
                # 当temp列表中的文件名输出到最后一个时跳出循环
                if num + 1 < len(temp):
                    Button(self, width=13, text=temp[num + 1], command=lambda: self.create2(temp[num + 1])).grid(row=i,
                                                                                                                 column=1,
                                                                                                                 stick=W,
                                                                                                                 pady=5)
                break
            for j in range(0, 3):
                su = temp[num]
                # lambda f=su: self.test(f) 形式可以很好解决因为循环导致每次调用test函数时只会传输su最后一次变动值的情况
                Button(self, width=13, text=su, command=lambda f=su: self.create2(f)).grid(row=i, column=j,
                                                                                           stick=W, pady=5)
                num += 1

    def create2(self, tem):
        with open('./' + 'log.txt', "w", encoding='utf-8')as f:
            f.write(tem)
        root = Tk()
        root.title('生词本')
        wordPage(root)#这是一个做菜单的类
        root.mainloop()#显示子页面

下面的代码就是wordPage类代码,这段代码做的一个子页面的菜单。是第二个效果图的源代码。

from tkinter import *
from wordEn import *
from wordCh import *


class wordPage(object):
    def __init__(self, master=None):  # 构造函数,这里的master值是main中传过来的root
        self.root = master
        self.root.geometry('%dx%d' % (240, 200))  # 设置窗口大小
        self.creatPage()  # 创建页面

    def creatPage(self):
        self.enPage = danEn(self.root)
        self.chPage = danCh(self.root)
        menubar = Menu(self.root)
        menubar.add_command(label='英译汉',command=self.en)
        menubar.add_command(label='汉译英', command=self.ch)
        self.root['menu'] = menubar

    def en(self):
        self.enPage.pack()
        self.chPage.pack_forget()

    def ch(self):
        self.enPage.pack_forget()
        self.chPage.pack()

下面代码是子页面其中的一个菜单功能,在shiyon 使用主页面值时在log.txt中读取,即可解决主页面给子页面传值的问题。

from tkinter import *
import random
import tkinter.messagebox


class danCh(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.root.geometry('%dx%d' % (240, 200))  # 设置窗口大小
        self.input = StringVar()  # 创建变量保存输入及输入内容的数据类型
        self.temp = StringVar()
        self.txt = StringVar()
        self.txt.set('')
        self.word = []
        self.flag = 0
        with open('./' + 'log.txt', "r", encoding='utf-8')as f:
            tem = f.read()
        with open('./ciBen/' + tem + '.txt', "r", encoding='utf-8')as f:
            for i in f.readlines():
                i = i.replace('\n', '')
                ii = i.split(' ')
                self.word.append(ii)
        random.shuffle(self.word)
        # print(self.word)
        self.temp.set(self.word[self.flag][1])
        self.creatPage()

    def creatPage(self):
        Label(self, text='单词: ').grid(row=0, stick=W, pady=10)  # 标签,位于w东
        Label(self, text=self.temp.get()).grid(row=0, column=1, stick=W)
        Label(self, text='翻译: ').grid(row=1, stick=W, pady=10)
        self.en = Entry(self, textvariable=self.input, width=22, justify=CENTER)
        self.en.grid(row=1, column=1, stick=W)
        but1 = Button(self, text='确认', command=self.panDuan)
        but1.grid(row=2, column=0, columnspan=2, stick=W, pady=10)
        but3 = Button(self, text='查看', command=self.seek)
        but3.grid(row=2, column=0, columnspan=2, stick=E, pady=10)
        but1.bind_all('<KeyPress-Up>', self.fun)  # 将回车键通过fun函数与确认按钮绑定
        but3.bind_all('<KeyPress-Down>', self.fun_seek)  # 将向Esc键通过fun_seek函数与查看按钮绑定
        self.lb = Label(self, text=self.txt.get(), font=('楷体', 15))
        self.lb.grid(row=3, column=0, columnspan=2, stick=N)

    def fun(self, tem):  # 会传来两个参数,一个是root,另一个则是回车键在系统中的命令代码,这里使用tem接收这行代码
        self.panDuan()

    def fun_seek(self, tem):  # 查看中介函数
        self.seek()

    def panDuan(self):
        if self.word[self.flag][0] == self.en.get():
            self.txt.set('正确')
            self.flag += 1
            if self.flag == len(self.word):
                tkinter.messagebox.showinfo('提示', '你已经答完了!')
            self.temp.set(self.word[self.flag][1])
            self.en.delete(0, END)
            self.creatPage()
        else:
            self.txt.set('错误')
            self.en.delete(0, END)
            self.creatPage()

    def seek(self):  # 查看正确答案函数
        self.txt.set(self.word[self.flag][0])
        self.creatPage()

3.传值步骤总结

        1、在点击按钮时有一个响应的函数,将按钮代表的值保存在一个txt文件中。

        2、在需要时打开txt文件读取即可。

二、Entry获取不到值的解决方法

1.问题介绍

        当我们在主页面中使用Entry获取输入时只需要textvariable这个参数即可,但是在子页面中获取时,我发现怎么也获取不到textvariable后面跟的变量,我也翻阅了许多博客,最后总结如下方法。

2.解决方法

代码如下:首先将Entry这样设置,textvariable可以不要

en = Entry(self, textvariable=self.input, width=22, justify=CENTER)
en.grid(row=1, column=1, stick=W)

当我们需要获取值时,可以使用如下的方法:

直接使用en去get他的值即可。不需要值时就是用delete删除即可

en.get()
en.delete(0, END)

3.总结 

这个方法有还是可以解决一些小问题的


总结

        以上就是我对创建子页面、主页面给子页面传值、Entry无法获取输入解决方法的介绍,有兴趣的朋友可以关注后续。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到