Tkinter隐藏窗口再让他显示出来的例子
隐藏主要是 : withdraw()函数。 重新显示出来主要是: update()和deiconify()函数。
来源:http://www.blog.pythonlibrary.org/2012/07/26/tkinter-how-to-show-hide-a-window/
Today we’re going to take a look at Tkinter! I was curious about how one would go about hiding a frame and then re-showing it using Tkinter and I kept finding threads (like this one) that talked about using withdraw() and deiconify() but didn’t really provide any usable code. In wxPython, I did this sort of thing using pubsub. We’ll go over three different versions of how to hide and show the root frame. My First Example A lot of example code for Tkinter is not very object oriented. What I mean by that is that the code I see isn’t in classes. To each their own, but I find GUI code easier to follow in a class. Anyway, that how I ended up creating my first example: import Tkinter as Tk ########################################################################
class MyApp(object):
"""""" #----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
self.root = parent
self.root.title("Main frame")
self.frame = Tk.Frame(parent)
self.frame.pack() btn = Tk.Button(self.frame, text="Open Frame", command=self.openFrame)
btn.pack() #----------------------------------------------------------------------
def hide(self):
""""""
self.root.withdraw() #----------------------------------------------------------------------
def openFrame(self):
""""""
self.hide()
otherFrame = Tk.Toplevel()
otherFrame.geometry("400x300")
otherFrame.title("otherFrame")
handler = lambda: self.onCloseOtherFrame(otherFrame)
btn = Tk.Button(otherFrame, text="Close", command=handler)
btn.pack() #----------------------------------------------------------------------
def onCloseOtherFrame(self, otherFrame):
""""""
otherFrame.destroy()
self.show() #----------------------------------------------------------------------
def show(self):
""""""
self.root.update()
self.root.deiconify() #----------------------------------------------------------------------
if __name__ == "__main__":
root = Tk.Tk()
root.geometry("800x600")
app = MyApp(root)
root.mainloop()
Let’s take a few moments to break this down a little. We have a simple class where we pass in a “root” object (Tk.Tk()) as the top-level parent. This in turn is used as the parent of the Tk.Frame. The pack() command is one of the geometry managers that Tkinter comes with. It allows you to “pack” widgets into columns or rows and has various options like fill, expand and side. Next we create a Tk.Button and pack it. If you don’t call pack (or one of the other geometry managers) then your widgets won’t appear at all. In the Button instantiation process, we pass it a parent, a string for its label and a command to be run when the button is clicked. When the user clicks the button, we create another Top level window and give it a different title, size and a close button. We use the lambda anonymous method to create the callback as we need to pass the otherFrame instance to the handler so we can close it. We could have just created the otherFrame as a class property (i.e. self.otherFrame) too and skipped the lambda, but if you do much with Tkinter, then you really need to get used to seeing that kind of callback setup. When the close button is called, it destroys the otherFrame and calls the show method, which shows the original frame. Some examples say that you need to call the update() method before you call the deiconify() one, however if you comment out the update() call, you’ll see that it works fine. At least it did on Windows with Python 2.6. Now let’s try splitting the second frame into its own class! Splitting the Second Frame into a Class
Putting the second frame into it’s very own class promotes code re-use and better organization of your code, especially if the second frame were to be really complex. Here’s one way to do it: import Tkinter as Tk ########################################################################
class OtherFrame(Tk.Toplevel):
"""""" #----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
Tk.Toplevel.__init__(self)
self.geometry("400x300")
self.title("otherFrame") ########################################################################
class MyApp(object):
"""""" #----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
self.root = parent
self.root.title("Main frame")
self.frame = Tk.Frame(parent)
self.frame.pack() btn = Tk.Button(self.frame, text="Open Frame", command=self.openFrame)
btn.pack() #----------------------------------------------------------------------
def hide(self):
""""""
self.root.withdraw() #----------------------------------------------------------------------
def openFrame(self):
""""""
self.hide()
subFrame = OtherFrame()
handler = lambda: self.onCloseOtherFrame(subFrame)
btn = Tk.Button(subFrame, text="Close", command=handler)
btn.pack() #----------------------------------------------------------------------
def onCloseOtherFrame(self, otherFrame):
""""""
otherFrame.destroy()
self.show() #----------------------------------------------------------------------
def show(self):
""""""
self.root.update()
self.root.deiconify() #----------------------------------------------------------------------
if __name__ == "__main__":
root = Tk.Tk()
root.geometry("800x600")
app = MyApp(root)
root.mainloop()
Now this is mostly the same as the first version of the code. It would be really nice to create the second frame’s button in the second frame’s class, but if we do that then it becomes hard to tell the original frame to deiconify. Still for completeness, let’s see how that would look: import Tkinter as Tk ########################################################################
class OtherFrame(Tk.Toplevel):
"""""" #----------------------------------------------------------------------
def __init__(self, original):
"""Constructor"""
self.original_frame = original
Tk.Toplevel.__init__(self)
self.geometry("400x300")
self.title("otherFrame") btn = Tk.Button(self, text="Close", command=self.onClose)
btn.pack() #----------------------------------------------------------------------
def onClose(self):
""""""
self.destroy()
self.original_frame.show() ########################################################################
class MyApp(object):
"""""" #----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
self.root = parent
self.root.title("Main frame")
self.frame = Tk.Frame(parent)
self.frame.pack() btn = Tk.Button(self.frame, text="Open Frame", command=self.openFrame)
btn.pack() #----------------------------------------------------------------------
def hide(self):
""""""
self.root.withdraw() #----------------------------------------------------------------------
def openFrame(self):
""""""
self.hide()
subFrame = OtherFrame(self) #----------------------------------------------------------------------
def show(self):
""""""
self.root.update()
self.root.deiconify() #----------------------------------------------------------------------
if __name__ == "__main__":
root = Tk.Tk()
root.geometry("800x600")
app = MyApp(root)
root.mainloop()
Note that in this version, we have to pass the instance of the MyApp class to the other frame so we can call its show method. You can also see that we no longer need the lambda function since we don’t need to pass the other frame instance to the handler any more. That makes things simpler. Still this is a fragile way of doing things. Why? Well if you decide to change the main frame’s show method to showFrame or anything else, then you have to remember to change it in the other class too or it breaks. This can get tedious very quickly if you are passing instances around to multiple classes. Fortunately there’s a simple solution and it’s called pubsub! Using pubsub to Communicate Between Tkinter Windows
You’ll need to go to pubsub’s website and install the package as it’s not included with Python. It IS included with wxPython, although I don’t think you can really use that version outside of wxPython very easily. Anyway, once you have it, you can follow along with this code: from pubsub import pub
import Tkinter as Tk ########################################################################
class OtherFrame(Tk.Toplevel):
"""""" #----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
Tk.Toplevel.__init__(self)
self.geometry("400x300")
self.title("otherFrame") # create the button
btn = Tk.Button(self, text="Close", command=self.onClose)
btn.pack() #----------------------------------------------------------------------
def onClose(self):
"""
closes the frame and sends a message to the main frame
"""
self.destroy()
pub.sendMessage("otherFrameClosed", arg1="data") ########################################################################
class MyApp(object):
"""""" #----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
self.root = parent
self.root.title("Main frame")
self.frame = Tk.Frame(parent)
self.frame.pack() btn = Tk.Button(self.frame, text="Open Frame", command=self.openFrame)
btn.pack() pub.subscribe(self.listener, "otherFrameClosed") #----------------------------------------------------------------------
def listener(self, arg1, arg2=None):
"""
pubsub listener - opens main frame when otherFrame closes
"""
self.show() #----------------------------------------------------------------------
def hide(self):
"""
hides main frame
"""
self.root.withdraw() #----------------------------------------------------------------------
def openFrame(self):
"""
opens other frame and hides main frame
"""
self.hide()
subFrame = OtherFrame() #----------------------------------------------------------------------
def show(self):
"""
shows main frame
"""
self.root.update()
self.root.deiconify() #----------------------------------------------------------------------
if __name__ == "__main__":
root = Tk.Tk()
root.geometry("800x600")
app = MyApp(root)
root.mainloop()
As might be expected, this code just integrate the pubsub stuff. We create a listener method in our main frame and we “register” it by calling pub.subscribe(self.listener, "otherFrameClosed")
The “signature” is otherFrameClosed. So if we publish a message with that signature, then the main frame and any other class that has subscribed to that signature will call their respective methods. In the other frame, we add a pub.sendMessage call to the end of our close method where we publish to that aforementioned signature and we pass along a dummy argument. You don’t have to do that, but I thought it would be better if you knew how to pass information between classes. You can pass pretty much any Python object / type that you want to. Wrapping Up
Now you know a little bit about Tkinter and a few of its top-level methods. You can make your frames disappear and reappear on command! You have also gotten a taste of the power of pubsub. Go forth and code with this new knowledge! Additional Resources
Tkinter Toplevel information from effbot
zetcode’s Tkinter tutorial
Python lambda
Fredrik Lundh’s intro to Tkinter
Tkinter隐藏窗口再让他显示出来的例子的更多相关文章
- 怎样让窗口不显示在任务栏和ALT+TAB中(隐藏窗口再嵌套,几乎是万能的办法)
之前想弄个像QQ旋风那样的悬浮窗口,就研究了下怎么让窗口不显示在任务栏中,方法其实很简单就是将窗口的扩张属性设置成WS_EX_TOOLWINDOW,MSDN中对该属性有详细介绍,代码如下: ::Set ...
- MFC无闪烁隐藏窗口
今天需要用到将窗口的程序隐藏,但是如果在OnInitDialog()中,直接写: ShowWindow(SW_HIDE); 是无效的,因为这本身就是个初始化窗口函数.也就是说,窗口在并没有显示出来的时 ...
- 在非UI线程中更改UI(Delphi使用隐藏窗口来处理,QT使用信号槽)
在Delphi里我记得是使用TThread.Synchronize(TThreadMethod),原理是利用了一个隐藏窗口来处理. 在QT Debug模式一下,碰到了同样的问题,显示错误: canno ...
- 将VirtualBox里安装的虚拟机在后台运行方法(在状态栏隐藏窗口)
由于工作和学习需要,经常要开一个虚拟机开测试和开发,虚拟机我选择Oracle公司的VirtualBox(用了几年了,感觉不错的一款产品),经常开着这个窗口感觉有些浪费资源,这样隐藏窗口就在需求了. 将 ...
- 在Form Load中设置showInTaskBar =false 或 隐藏窗口 this.Hide()时会导致注册的全局快捷键无效
在Form Load中设置showInTaskBar =false 或 隐藏窗口 this.Hide() 会导致注册的全局快捷键无效. 反正是其中一个,有点记不清了. 在Form Shown中s ...
- C# 实现窗口程序winform像QQ一样靠近桌面边缘自动隐藏窗口
实现原理: 实现这个功能的原理步骤如下: 1.判断窗体程序是否靠近桌面边缘: 2.获取桌面屏幕大小与窗体程序大小: 3.把窗体程序显示在桌面以外隐藏起来,预留部分窗体方便用户拉出程序: 4.判断鼠标是 ...
- 实现:调用API函数ShowWindow()来隐藏窗口
只需要将相应代码复制即可. 代码如下: #include <iostream> #include <windows.h> int main() { HWND hDos; //声 ...
- electron开发 - mac关闭和隐藏窗口
针对mac平台的app let willQuitApp = false; // 控制退出方式 mainWindow.on('close', (e) => { if (willQuitApp) { ...
- C# 显示、隐藏窗口对应的任务栏
WPF中全屏窗口,会自动隐藏任务栏. 那非全屏窗口如何隐藏任务栏?甚至有没有一种场景,隐藏任务后自定义一套系统任务栏来显示? 以下会分阶段讲述一些概念 1. 主屏任务栏 任务栏,其实也是一个窗口,主屏 ...
随机推荐
- 在JDBC中使用PreparedStatement代替Statement,同时预防SQL注入
本篇讲诉为何在JDBC操作数据库的过程中,要使用PreparedStatement对象来代替Statement对象. 在前面的JDBC学习中,对于Statement对象,我们已经知道是封装SQL语句并 ...
- 一个与Log4j相关的死锁(转)
这个死锁的原因:一个动作需要两个临界对象.静态同步方法,就是一个临界对象.这种场景,静态同步方法每次只能有一个线程持有.如果存在另一个临界对象,静态同步方法中也需要获取这个临界对象.即一个动作需要两个 ...
- J2EE SSH学习(二)安装Eclipse插件和第一个Eclipse项目
(一)安装Eclipse插件 Eclipse有很多功能很强大的插件,我现在作为一个菜鸟只知道插件的功能通常都很牛叉实用或者很有趣,那么该怎么安装Eclipse插件呢? 我使用的是Eclipse 4.3 ...
- Ext JS4百强应用:设置textfield的悬浮提示信息 --第8强
在Extjs4中有时候我们需要textfield的提示信息,但是我们发现textfield并没有这样的配置项. 这时候我们就要另想方法:我们需要在鼠标悬停在textfield组件的时候进行信息的提示, ...
- Delphi图像处理 -- 最大值
阅读提示: <Delphi图像处理>系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM. <C++图像处理>系列以代码清晰,可读性为主,全部使用C ...
- UE4的编程C++创建一个FPSproject(两)角色网格、动画、HUD、子弹类
立即归还,本文将总结所有这些整理UE4有关角色的网络格.动画.子弹类HUD一个简单的实现. (五)角色加入网格 Character类为我们默认创建了一个SkeletaMeshComponent组件,所 ...
- [Ext JS 4]性能优化
一般的优化技巧 1. 检查你定义的时间监听器 正确的设置事件监听器对性能会有很大的影响. 举例来说, 在定义一个store的时候,设置一个load 的事件去触发从后台读取数据,如果设置single 的 ...
- [置顶] 强大的JQuery
JQuery初识 为了简化JS的开发,一些JS库诞生了,JQuery就是其中的一个.JQuery是一个兼容多浏览器的Javascript框架.是轻量级的JS库.jQuery为用户提供了丰富的文档说明, ...
- Python之常用模块(待更新)
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- 搜索引擎爬虫蜘蛛的USERAGENT大全
搜索引擎爬虫蜘蛛的USERAGENT大全 搜索引擎爬虫蜘蛛的USERAGENT收集,方便制作采集的朋友. 百度爬虫 * Baiduspider+(+http://www.baidu.com/sea ...