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

一、标准窗口

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

  1. from tkinter.simpledialog import askstring, askinteger, askfloat
完整例子
  1. import tkinter as tk
  2. from tkinter.simpledialog import askstring, askinteger, askfloat
  3. # 接收一个整数
  4. def print_integer():
  5. res = askinteger("Spam", "Egg count", initialvalue=12*12)
  6. print(res)
  7. # 接收一个浮点数
  8. def print_float():
  9. res = askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100)
  10. print(res)
  11. # 接收一个字符串
  12. def print_string():
  13. res = askstring("Spam", "Egg label")
  14. print(res)
  15. root = tk.Tk()
  16. tk.Button(root, text='取一个字符串', command=print_string).pack()
  17. tk.Button(root, text='取一个整数', command=print_integer).pack()
  18. tk.Button(root, text='取一个浮点数', command=print_float).pack()
  19. root.mainloop()

二、自定义窗口

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

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

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

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

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

1)松耦合

说明

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

要点

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

完整代码:

  1. import tkinter as tk
  2. '''松耦合'''
  3. # 弹窗
  4. class MyDialog(tk.Toplevel):
  5. def __init__(self):
  6. super().__init__()
  7. self.title('设置用户信息')
  8. # 弹窗界面
  9. self.setup_UI()
  10. def setup_UI(self):
  11. # 第一行(两列)
  12. row1 = tk.Frame(self)
  13. row1.pack(fill="x")
  14. tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
  15. self.name = tk.StringVar()
  16. tk.Entry(row1, textvariable=self.name, width=20).pack(side=tk.LEFT)
  17. # 第二行
  18. row2 = tk.Frame(self)
  19. row2.pack(fill="x", ipadx=1, ipady=1)
  20. tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
  21. self.age = tk.IntVar()
  22. tk.Entry(row2, textvariable=self.age, width=20).pack(side=tk.LEFT)
  23. # 第三行
  24. row3 = tk.Frame(self)
  25. row3.pack(fill="x")
  26. tk.Button(row3, text="取消", command=self.cancel).pack(side=tk.RIGHT)
  27. tk.Button(row3, text="确定", command=self.ok).pack(side=tk.RIGHT)
  28. def ok(self):
  29. self.userinfo = [self.name.get(), self.age.get()] # 设置数据
  30. self.destroy() # 销毁窗口
  31. def cancel(self):
  32. self.userinfo = None # 空!
  33. self.destroy()
  34. # 主窗
  35. class MyApp(tk.Tk):
  36. def __init__(self):
  37. super().__init__()
  38. #self.pack() # 若继承 tk.Frame ,此句必须有!
  39. self.title('用户信息')
  40. # 程序参数/数据
  41. self.name = '张三'
  42. self.age = 30
  43. # 程序界面
  44. self.setupUI()
  45. def setupUI(self):
  46. # 第一行(两列)
  47. row1 = tk.Frame(self)
  48. row1.pack(fill="x")
  49. tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
  50. self.l1 = tk.Label(row1, text=self.name, width=20)
  51. self.l1.pack(side=tk.LEFT)
  52. # 第二行
  53. row2 = tk.Frame(self)
  54. row2.pack(fill="x")
  55. tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
  56. self.l2 = tk.Label(row2, text=self.age, width=20)
  57. self.l2.pack(side=tk.LEFT)
  58. # 第三行
  59. row3 = tk.Frame(self)
  60. row3.pack(fill="x")
  61. tk.Button(row3, text="设置", command=self.setup_config).pack(side=tk.RIGHT)
  62. # 设置参数
  63. def setup_config(self):
  64. # 接收弹窗的数据
  65. res = self.ask_userinfo()
  66. #print(res)
  67. if res is None: return
  68. # 更改参数
  69. self.name, self.age = res
  70. # 更新界面
  71. self.l1.config(text=self.name)
  72. self.l2.config(text=self.age)
  73. # 弹窗
  74. def ask_userinfo(self):
  75. inputDialog = MyDialog()
  76. self.wait_window(inputDialog) # 这一句很重要!!!
  77. return inputDialog.userinfo
  78. if __name__ == '__main__':
  79. app = MyApp()
  80. app.mainloop()

2)紧耦合

说明

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

要点

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

完整代码:

  1. import tkinter as tk
  2. '''紧耦合'''
  3. # 弹窗
  4. class PopupDialog(tk.Toplevel):
  5. def __init__(self, parent):
  6. super().__init__()
  7. self.title('设置用户信息')
  8. self.parent = parent # 显式地保留父窗口
  9. # 第一行(两列)
  10. row1 = tk.Frame(self)
  11. row1.pack(fill="x")
  12. tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
  13. self.name = tk.StringVar()
  14. tk.Entry(row1, textvariable=self.name, width=20).pack(side=tk.LEFT)
  15. # 第二行
  16. row2 = tk.Frame(self)
  17. row2.pack(fill="x", ipadx=1, ipady=1)
  18. tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
  19. self.age = tk.IntVar()
  20. tk.Entry(row2, textvariable=self.age, width=20).pack(side=tk.LEFT)
  21. # 第三行
  22. row3 = tk.Frame(self)
  23. row3.pack(fill="x")
  24. tk.Button(row3, text="取消", command=self.cancel).pack(side=tk.RIGHT)
  25. tk.Button(row3, text="确定", command=self.ok).pack(side=tk.RIGHT)
  26. def ok(self):
  27. # 显式地更改父窗口参数
  28. self.parent.name = self.name.get()
  29. self.parent.age = self.age.get()
  30. # 显式地更新父窗口界面
  31. self.parent.l1.config(text=self.parent.name)
  32. self.parent.l2.config(text=self.parent.age)
  33. self.destroy() # 销毁窗口
  34. def cancel(self):
  35. self.destroy()
  36. # 主窗
  37. class MyApp(tk.Tk):
  38. def __init__(self):
  39. super().__init__()
  40. # self.pack() # 若继承 tk.Frame,此句必须有!!!
  41. self.title('用户信息')
  42. # 程序参数
  43. self.name = '张三'
  44. self.age = 30
  45. # 程序界面
  46. self.setupUI()
  47. def setupUI(self):
  48. # 第一行(两列)
  49. row1 = tk.Frame(self)
  50. row1.pack(fill="x")
  51. tk.Label(row1, text='姓名:', width=8).pack(side=tk.LEFT)
  52. self.l1 = tk.Label(row1, text=self.name, width=20)
  53. self.l1.pack(side=tk.LEFT)
  54. # 第二行
  55. row2 = tk.Frame(self)
  56. row2.pack(fill="x")
  57. tk.Label(row2, text='年龄:', width=8).pack(side=tk.LEFT)
  58. self.l2 = tk.Label(row2, text=self.age, width=20)
  59. self.l2.pack(side=tk.LEFT)
  60. # 第三行
  61. row3 = tk.Frame(self)
  62. row3.pack(fill="x")
  63. tk.Button(row3, text="设置", command=self.setup_config).pack(side=tk.RIGHT)
  64. # 设置参数
  65. def setup_config(self):
  66. pw = PopupDialog(self)
  67. self.wait_window(pw) # 这一句很重要!!!
  68. return
  69. if __name__ == '__main__':
  70. app = MyApp()
  71. app.mainloop()

效果图

tkinter 弹出窗口 传值回到 主窗口的更多相关文章

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

    这篇文章主要介绍了Python tkinter模块弹出窗口及传值回到主窗口操作,结合实例形式分析了Python使用tkinter模块实现的弹出窗口及参数传递相关操作技巧,需要的朋友可以参考下 本文实例 ...

  2. js制作带有遮罩弹出层实现登录小窗口

    要实现的效果如下 点击“登录”按钮后,弹出登录小窗口,并且有遮罩层(这个名词还是百度知道的,以前只知道效果,却不知道名字) 在没有点击“登录”按钮之前登录小窗口不显示,点击“登录”按钮后小窗口显示,并 ...

  3. PHP JS HTML ASP页面跳转代码 延时跳转代码 返回到上一界面并刷新 JS弹出指定大小的新窗口

    1.PHP延时跳转代码 //跳转到浏览界面 header("Refresh:1;url=machine_list.php"); //不延时 <?php header(&quo ...

  4. 如何禁用MySql总是定时弹出一个MySQLInstallerConsole.exe的窗口

    如何禁用MySql总是定时弹出一个MySQLInstallerConsole.exe的窗口 禁用mysql总是弹出一个安装框的定时任务这一条安装命令,Installing MySQL 5.6.21 u ...

  5. Python实现使用tkinter弹出输入框输入数字, 具有确定输入和清除功能

    Python3.6中用tkinter, 弹出可以输入数字的输入框. # Copyright (c) 2017-7-21 ZhengPeng All rights reserved. def pop_u ...

  6. WPF:验证登录后关闭登录窗口,显示主窗口的解决方法

    http://www.27ba.com/post/145.html WPF:验证登录后关闭登录窗口,显示主窗口的解决方法 最近想做一个基于Socket的通讯工具,想模仿QQ那样,需要先登录,登录成功后 ...

  7. 如何获得 Qt窗口部件在主窗口中的位置--确定鼠标是否在某一控件上与在控件上的位置

    用Qt Creator 设计程序时,最方便的就是ui设计器,可以很容易的得到想要的布局. 但是这样自动布局带来的后果是很难知道窗口中某一部件在主窗口中的相对位置. 在处理子窗口鼠标事件时变的很麻烦.主 ...

  8. Qt 子窗口监听主窗口信号

    Qt 子窗口监听主窗口信号(转载)  原文链接:https://www.cnblogs.com/ybqjymy/p/12169762.html 1 MainWindow *ptr = NULL; 2 ...

  9. 点击一个超链接,弹出固定大小的新窗口(js实现)

    1.最基本的弹出窗口代码 <SCRIPT LANGUAGE="javascript"> <!-- window.open ('page.html') --> ...

随机推荐

  1. 解决 ModuleNotFoundError: No module named 'pip'

    安装其它python包时,提示说 pip 10.0.1可用,就更新了一下,但是 更新过程中出现了错误,如图所示 因为这个错误导致 pip找不到, 可以首先执行  python -m ensurepip ...

  2. python unnitest 经验总结

    由于我的用例是数据驱动,每个用例保存为一个txt或者xls文件,执行时候需要读取文件,并将所有变量实例化成一个用例: 之前自己设计了框架,由于考虑需要生成一个美观通用的报告格式(原格式都是手写的htm ...

  3. 2. DAS,NAS,SAN在数据库存储上的应用

    一. 硬盘接口类型1. 并行接口还是串行接口(1) 并行接口,指的是并行传输的接口,比如有0~9十个数字,用10条传输线,那么每根线只需要传输一位数字,即可完成.从理论上看,并行传输效率很高,但是由于 ...

  4. RBAC用户权限管理数据库设计【转载】

    本文转载自:https://www.kancloud.cn/martist/ma_zhao_liu/374123 简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成“用户-角色-权 ...

  5. 大于2t的磁盘分区,并格式化ext4挂载

    1:MBR分区表:(MBR含义:主引导记录) 所支持的最大卷:2T (T; terabytes,1TB=1024GB) 对分区的设限:最多4个主分区或3个主分区加一个扩展分区. 2:GPT分区表:(G ...

  6. META-INF下文件读取

    protected String getProperty(String name) {        String file = "/META-INF/jndi.properties&quo ...

  7. windows使用

    将桌面.我的文档.收藏夹等转移到其他盘 方法很多,介绍如下: 一.新装的系统,桌面.我的文档.收藏夹等都是默认在C盘的,并且这些数据都是用户经常用到的一些数据.为了避免以后系统崩溃所带来的危险,最好的 ...

  8. ip 命令的使用

    网上相似的资源很多,可以参考如下资料: man ip ip help 博客链接: https://linoxide.com/linux-command/use-ip-command-linux/ ht ...

  9. Java-Swing常用布局管理器

    http://www.cnblogs.com/hthuang/p/3460234.html   5.Java-Swing常用布局管理器       应用布局管理器都属于相对布局,各组件位置可随界面大小 ...

  10. Ecstore 默认图片压缩质量差的问题解决方法

    修改app/image/lib/clip.php文件 }elseif( function_exists('imagecopyresampled')){ $quality = 80; $image_p ...