Python tkinter模块弹出窗口及传值回到主窗口操作详解


Posted in Python onJuly 28, 2017

本文实例讲述了Python tkinter模块弹出窗口及传值回到主窗口操作。分享给大家供大家参考,具体如下:

有些时候,我们需要使用弹出窗口,对程序的运行参数进行设置。有两种选择

一、标准窗口

如果只对一个参数进行设置(或者说从弹出窗口取回一个值),那么可以使用simpledialog,导入方法:

from tkinter.simpledialog import askstring, askinteger, askfloat

完整例子

import tkinter as tk
from tkinter.simpledialog import askstring, askinteger, askfloat
# 接收一个整数
def print_integer():
  res = askinteger("Spam", "Egg count", initialvalue=12*12)
  print(res)
# 接收一个浮点数
def print_float():
  res = askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100)
  print(res)
# 接收一个字符串
def print_string():
  res = askstring("Spam", "Egg label")
  print(res)
root = tk.Tk()
tk.Button(root, text='取一个字符串', command=print_string).pack()
tk.Button(root, text='取一个整数', command=print_integer).pack()
tk.Button(root, text='取一个浮点数', command=print_float).pack()
root.mainloop()

二、自定义窗口

如果要设置的参数个数超过两个,那么tkinter提供的标准窗口就处理不了了。

这就需要自定义一个窗口,那么问题来了:怎样将自定义窗口中的数据传回主窗口?

百度查询,不外乎两种方法:全局变量(global)、对象变量([]、{}等),都不是我想要的。

然后,去 stackoverflow 逛了一下,综合了个问题的答案,得到两个本人比较满意的方案。

一种是松耦合,另一种是紧耦合

1)松耦合

说明:

主窗类,继承了 tk.Tk
弹窗类,继承了 tk.Toplevel

要点:

弹窗,将多个数据,打包,放入一个名为 username 的私有 list 对象,销毁弹窗
主窗,待弹窗运行后,通过wait_window方法,取得弹窗的名为 username 私有变量

完整代码:

import tkinter as tk
'''松耦合'''
# 弹窗
class MyDialog(tk.Toplevel):
  def __init__(self):
    super().__init__()
    self.title('设置用户信息')
    # 弹窗界面
    self.setup_UI()
  def setup_UI(self):
    # 第一行(两列)
    row1 = tk.Frame(self)
    row1.pack(fill="x")
    tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
    self.name = tk.StringVar()
    tk.Entry(row1, textvariable=self.name, width=20).pack(side=tk.LEFT)
    # 第二行
    row2 = tk.Frame(self)
    row2.pack(fill="x", ipadx=1, ipady=1)
    tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
    self.age = tk.IntVar()
    tk.Entry(row2, textvariable=self.age, width=20).pack(side=tk.LEFT)
    # 第三行
    row3 = tk.Frame(self)
    row3.pack(fill="x")
    tk.Button(row3, text="取消", command=self.cancel).pack(side=tk.RIGHT)
    tk.Button(row3, text="确定", command=self.ok).pack(side=tk.RIGHT)
  def ok(self):
    self.userinfo = [self.name.get(), self.age.get()] # 设置数据
    self.destroy() # 销毁窗口
  def cancel(self):
    self.userinfo = None # 空!
    self.destroy()
# 主窗
class MyApp(tk.Tk):
  def __init__(self):
    super().__init__()
    #self.pack() # 若继承 tk.Frame ,此句必须有!
    self.title('用户信息')
    # 程序参数/数据
    self.name = '张三'
    self.age = 30
    # 程序界面
    self.setupUI()
  def setupUI(self):
    # 第一行(两列)
    row1 = tk.Frame(self)
    row1.pack(fill="x")
    tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
    self.l1 = tk.Label(row1, text=self.name, width=20)
    self.l1.pack(side=tk.LEFT)
    # 第二行
    row2 = tk.Frame(self)
    row2.pack(fill="x")
    tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
    self.l2 = tk.Label(row2, text=self.age, width=20)
    self.l2.pack(side=tk.LEFT)
    # 第三行
    row3 = tk.Frame(self)
    row3.pack(fill="x")
    tk.Button(row3, text="设置", command=self.setup_config).pack(side=tk.RIGHT)
  # 设置参数
  def setup_config(self):
    # 接收弹窗的数据
    res = self.ask_userinfo()
    #print(res)
    if res is None: return
    # 更改参数
    self.name, self.age = res
    # 更新界面
    self.l1.config(text=self.name)
    self.l2.config(text=self.age)
  # 弹窗
  def ask_userinfo(self):
    inputDialog = MyDialog()
    self.wait_window(inputDialog) # 这一句很重要!!!
    return inputDialog.userinfo
if __name__ == '__main__':
  app = MyApp()
  app.mainloop()

2)紧耦合

说明:

主窗类,继承了 tk.Tk
弹窗类,继承了 tk.Toplevel

要点:

弹窗,显式地保存父窗口,显式地修改父窗口数据,显式地更新父窗口部件,最后销毁弹窗
主窗,待弹窗运行后,通过wait_window方法,返回 None

完整代码:

import tkinter as tk
'''紧耦合'''
# 弹窗
class PopupDialog(tk.Toplevel):
  def __init__(self, parent):
    super().__init__()
    self.title('设置用户信息')
    self.parent = parent # 显式地保留父窗口
    # 第一行(两列)
    row1 = tk.Frame(self)
    row1.pack(fill="x")
    tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
    self.name = tk.StringVar()
    tk.Entry(row1, textvariable=self.name, width=20).pack(side=tk.LEFT)
    # 第二行
    row2 = tk.Frame(self)
    row2.pack(fill="x", ipadx=1, ipady=1)
    tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
    self.age = tk.IntVar()
    tk.Entry(row2, textvariable=self.age, width=20).pack(side=tk.LEFT)
    # 第三行
    row3 = tk.Frame(self)
    row3.pack(fill="x")
    tk.Button(row3, text="取消", command=self.cancel).pack(side=tk.RIGHT)
    tk.Button(row3, text="确定", command=self.ok).pack(side=tk.RIGHT)
  def ok(self):
    # 显式地更改父窗口参数
    self.parent.name = self.name.get()
    self.parent.age = self.age.get()
    # 显式地更新父窗口界面
    self.parent.l1.config(text=self.parent.name)
    self.parent.l2.config(text=self.parent.age)
    self.destroy() # 销毁窗口
  def cancel(self):
    self.destroy()
# 主窗
class MyApp(tk.Tk):
  def __init__(self):
    super().__init__()
    # self.pack() # 若继承 tk.Frame,此句必须有!!!
    self.title('用户信息')
    # 程序参数
    self.name = '张三'
    self.age = 30
    # 程序界面
    self.setupUI()
  def setupUI(self):
    # 第一行(两列)
    row1 = tk.Frame(self)
    row1.pack(fill="x")
    tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
    self.l1 = tk.Label(row1, text=self.name, width=20)
    self.l1.pack(side=tk.LEFT)
    # 第二行
    row2 = tk.Frame(self)
    row2.pack(fill="x")
    tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
    self.l2 = tk.Label(row2, text=self.age, width=20)
    self.l2.pack(side=tk.LEFT)
    # 第三行
    row3 = tk.Frame(self)
    row3.pack(fill="x")
    tk.Button(row3, text="设置", command=self.setup_config).pack(side=tk.RIGHT)
  # 设置参数
  def setup_config(self):
    pw = PopupDialog(self)
    self.wait_window(pw) # 这一句很重要!!!
    return
if __name__ == '__main__':
  app = MyApp()
  app.mainloop()

效果图

Python tkinter模块弹出窗口及传值回到主窗口操作详解

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python实现Tab自动补全和历史命令管理的方法
Mar 12 Python
python实现的简单抽奖系统实例
May 22 Python
python中OrderedDict的使用方法详解
May 05 Python
Python+matplotlib+numpy实现在不同平面的二维条形图
Jan 02 Python
详解Python3 基本数据类型
Apr 19 Python
python3安装crypto出错及解决方法
Jul 30 Python
python 叠加等边三角形的绘制的实现
Aug 14 Python
python实现身份证实名认证的方法实例
Nov 08 Python
python数据化运营的重要意义
Nov 25 Python
python3 webp转gif格式的实现示例
Dec 10 Python
python怎么提高计算速度
Jun 11 Python
python二维图制作的实例代码
Dec 03 Python
Python单体模式的几种常见实现方法详解
Jul 28 #Python
深入浅出分析Python装饰器用法
Jul 28 #Python
分享一个可以生成各种进制格式IP的小工具实例代码
Jul 28 #Python
Python使用sorted排序的方法小结
Jul 28 #Python
python发送邮件实例分享
Jul 28 #Python
Python分治法定义与应用实例详解
Jul 28 #Python
Python更新数据库脚本两种方法及对比介绍
Jul 27 #Python
You might like
Apache, PHP在Windows 9x/NT下的安装与配置 (一)
2006/10/09 PHP
PHP 程序员也要学会使用“异常”
2009/06/16 PHP
php处理斐波那契数列非递归方法
2012/02/04 PHP
解析centos中Apache、php、mysql 默认安装路径
2013/06/25 PHP
THINKPHP5分页数据对象处理过程解析
2020/10/28 PHP
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
2011/03/12 Javascript
19个很有用的 JavaScript库推荐
2011/06/27 Javascript
javascript学习基础笔记之DOM对象操作
2011/11/03 Javascript
js过滤HTML标签以及空格的思路及代码
2013/05/24 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
jQuery ajax方法传递中文时出现中文乱码的解决方法
2016/07/25 Javascript
jQuery EasyUI Accordion可伸缩面板组件使用详解
2017/02/28 Javascript
vue.js实现的全选与全不选功能示例【基于elementui】
2018/12/03 Javascript
浅谈javascript中的prototype和__proto__的理解
2019/04/07 Javascript
原生javascript运动函数的封装示例【匀速、抛物线、多属性的运动等】
2020/02/23 Javascript
浅谈javascript事件环微任务和宏任务队列原理
2020/09/12 Javascript
python实现xlsx文件分析详解
2018/01/02 Python
matplotlib绘制动画代码示例
2018/01/02 Python
Python实现字符串的逆序 C++字符串逆序算法
2020/05/28 Python
python 中字典嵌套列表的方法
2018/07/03 Python
Python 隐藏输入密码时屏幕回显的实例
2019/02/19 Python
Python编程学习之如何判断3个数的大小
2019/08/07 Python
关于Pytorch的MNIST数据集的预处理详解
2020/01/10 Python
TensorFlow实现打印每一层的输出
2020/01/21 Python
Python实现ATM系统
2020/02/17 Python
Python实现鼠标自动在屏幕上随机移动功能
2020/03/14 Python
CSS3实现大小不一的粒子旋转加载动画
2016/04/21 HTML / CSS
小学毕业感言150字
2014/02/05 职场文书
教师演讲稿开场白
2014/08/25 职场文书
我的大学四年规划书范文2014
2014/09/26 职场文书
幼儿园教师节活动总结
2015/03/23 职场文书
2015国际残疾人日活动总结
2015/03/24 职场文书
2015年幼儿园班主任个人工作总结
2015/10/22 职场文书
小学六年级班主任工作经验交流材料
2015/11/02 职场文书
Django+Celery实现定时任务的示例
2021/06/23 Python
多台电脑共享文件怎么设置?多台电脑共享文件操作教程
2022/04/08 数码科技