tkinter的GUI设计:界面与逻辑分离(二)-- 菜单栏

由于要用到文件对话框和消息对话框,所以先给出下面的列表。

py2 与 py3 中 tkinter 的变化:
  Tkinter → tkinter tkMessageBox → tkinter.messagebox tkColorChooser → tkinter.colorchooser tkFileDialog → tkinter.filedialog tkCommonDialog → tkinter.commondialog tkSimpleDialog → tkinter.simpledialog tkFont → tkinter.font Tkdnd → tkinter.dnd ScrolledText → tkinter.scrolledtext Tix → tkinter.tix ttk → tkinter.ttk

说明:本文基于:win7 + python34

知识点:
1、文件夹对话框 tkinter.filedialog
2、消息框 tkinter.messagebox
3、菜单栏
4、下拉列表
Combobox 的设置

效果图:



代码:
import os
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox


class Application(tk.Tk):
    '''
    文件夹选择程序
        界面与逻辑分离
    '''
    
    def __init__(self):
        '''初始化'''
        super().__init__() # 有点相当于tk.Tk()
        
        self.createWidgets()

    def createWidgets(self):
        '''界面'''
        self.title('文件夹选择程序')
        self.columnconfigure(0, minsize=50)
        
        # 定义一些变量
        self.entryvar = tk.StringVar()
        self.keyvar = tk.StringVar()
        self.keyvar.set('关键字')
        items = ['BufferPool','Close','Data Capture','Compress','Pqty','Sqty']

        # 先定义顶部和内容两个Frame,用来放置下面的部件
        topframe = tk.Frame(self, height=80)
        contentframe = tk.Frame(self)
        topframe.pack(side=tk.TOP)
        contentframe.pack(side=tk.TOP)
        
        # 顶部区域(四个部件)
        # -- 前三个直接用 tk 的 widgets,第四个下拉列表 tk 没有,ttk 才有,比较麻烦
        glabel = tk.Label(topframe, text='当前文件夹:')
        gentry = tk.Entry(topframe, textvariable=self.entryvar)
        gbutton = tk.Button(topframe, command=self.__opendir, text='选择')
        gcombobox = ttk.Combobox(topframe, values=items, textvariable=self.keyvar)
        # -- 绑定事件
        gentry.bind('<Return>', func=self.__refresh)
        #gcombobox.bind('<ComboboxSelected>', func=self.__refresh) # 绑定 <ComboboxSelected> 事件
        # -- 放置位置
        glabel.grid(row=0, column=0, sticky=tk.W)
        gentry.grid(row=0, column=1)
        gbutton.grid(row=0, column=2)
        gcombobox.grid(row=0, column=3)
        
        # 内容区域(三个部件)
        # -- 前两个滚动条一个竖直一个水平
        rightbar = tk.Scrollbar(contentframe, orient=tk.VERTICAL)
        bottombar = tk.Scrollbar(contentframe, orient=tk.HORIZONTAL)
        self.textbox = tk.Text(contentframe, yscrollcommand=rightbar.set, xscrollcommand=bottombar.set)
        # -- 放置位置
        rightbar.pack(side =tk.RIGHT, fill=tk.Y)
        bottombar.pack(side=tk.BOTTOM, fill=tk.X)
        self.textbox.pack(side=tk.LEFT, fill=tk.BOTH)
        # -- 设置命令
        rightbar.config(command=self.textbox.yview)
        bottombar.config(command=self.textbox.xview)
        
        
    def __opendir(self):
        '''打开文件夹的逻辑'''
        self.textbox.delete('1.0', tk.END) # 先删除所有
        
        self.dirname = filedialog.askdirectory() # 打开文件夹对话框
        self.entryvar.set(self.dirname) # 设置变量entryvar,等同于设置部件Entry
        
        if not self.dirname:
            messagebox.showwarning('警告', message='未选择文件夹!')  # 弹出消息提示框
        
        self.dirlist = os.listdir(self.entryvar.get())
        for eachdir in self.dirlist:
            self.textbox.insert(tk.END, eachdir+'\r\n')
            
        self.textbox.update()
        
        
    def __refresh(self, event=None):
        '''更新的逻辑'''
        self.textbox.delete('1.0', tk.END) # 先删除所有
        
        self.dirlist = os.listdir(self.entryvar.get())
        for eachdir in self.dirlist:
            self.textbox.insert(tk.END, eachdir+'\r\n')
            
        self.textbox.update()
        
        
    def addmenu(self, Menu):
        '''添加菜单'''
        Menu(self)
        
        
        
class MyMenu():
    '''菜单类'''
    
    def __init__(self, root):
        '''初始化菜单'''
        self.menubar = tk.Menu(root) # 创建菜单栏
        
        # 创建“文件”下拉菜单
        filemenu = tk.Menu(self.menubar, tearoff=0)
        filemenu.add_command(label="打开", command=self.file_open)
        filemenu.add_command(label="新建", command=self.file_new)
        filemenu.add_command(label="保存", command=self.file_save)
        filemenu.add_separator()
        filemenu.add_command(label="退出", command=root.quit)
        
        # 创建“编辑”下拉菜单
        editmenu = tk.Menu(self.menubar, tearoff=0)
        editmenu.add_command(label="剪切", command=self.edit_cut)
        editmenu.add_command(label="复制", command=self.edit_copy)
        editmenu.add_command(label="粘贴", command=self.edit_paste)
        
        # 创建“帮助”下拉菜单
        helpmenu = tk.Menu(self.menubar, tearoff=0)
        helpmenu.add_command(label="关于", command=self.help_about)
        
        # 将前面三个菜单加到菜单栏
        self.menubar.add_cascade(label="文件", menu=filemenu)
        self.menubar.add_cascade(label="编辑", menu=editmenu)
        self.menubar.add_cascade(label="帮助", menu=helpmenu)
        
        # 最后再将菜单栏整个加到窗口 root
        root.config(menu=self.menubar)
        
    def file_open(self):
        messagebox.showinfo('打开', '文件-打开!')  # 消息提示框
        pass
        
    def file_new(self):
        messagebox.showinfo('新建', '文件-新建!')  # 消息提示框
        pass
        
    def file_save(self):
        messagebox.showinfo('保存', '文件-保存!')  # 消息提示框
        pass
        
    def edit_cut(self):
        messagebox.showinfo('剪切', '编辑-剪切!')  # 消息提示框
        pass
        
    def edit_copy(self):
        messagebox.showinfo('复制', '编辑-复制!')  # 消息提示框
        pass
        
    def edit_paste(self):
        messagebox.showinfo('粘贴', '编辑-粘贴!')  # 消息提示框
        pass
        
    def help_about(self):
        messagebox.showinfo('关于', '作者:kinfinger \n verion 1.0 \n 感谢您的使用! \n kinfinge@gmail.com ')  # 弹出消息提示框
        
    
    
if __name__ == '__main__':
    # 实例化Application
    app = Application()
    
    # 添加菜单:
    app.addmenu(MyMenu)
    
    # 主消息循环:
    app.mainloop()

 

展开阅读全文

[franklyTalk] 从界面逻辑分离开始

09-14

最初的一个讨论的帖子是rnhttp://community.csdn.net/Expert/topic/4249/4249906.xml?temp=.3769953rn在这个帖子中lvhaiyan (寒雪)提出了这样一个问题:rn请大家谈谈多人vc程序,界面、代码怎么分工,以及,每人写的代码怎么集中到一个程序中去,请大家积极讨论,希望对大家都有好处。rnrn这个问题说容易也很容易,说难也非常难。这里面不仅仅是一个编码或是分工的问题,更是一种深层次的思想问题。可能说的玄乎了,开个新贴我对那个帖子的再说说自己的一些体会,更是一个新的讨论的开始。rnrn从正式开始学C++到现在也有三四年的时间了,我回过头来看一下走过的轨迹,从C++语言本身到Windows系统到MFC到STL,boost,loki这些类库再是模板类还有COM,大概也就这些内容,C++ Primer,Advanced Windows,深入浅出MFC那些书还不时的会去翻翻看看,是这三本书带领我走进了编程的世界。rnrn其实在初学那段时间极端热衷在csdn.net中VC/C++中回帖,那个时候觉得牛啊,全T.M.D是星星,我也是孜孜不倦看贴回帖,不断游走与vckbase,codeproject,codeguru,慢慢的自己的专家分也到了5位数,那个时候的兴奋啊,但现在回过头来想想,真的没什么,都是一些重复性的劳动,自己并没有在这种回帖中有更大的发展空间了,所以也就慢慢的退了出来。rnrn我相信很多用VC的人的都觉得VC是目前最牛X的工具,C++是世界上最流行的语言。会MFC就可以开发出一流的软件。所以不屑于java,不屑于ruby,python,perl那些不上台面的动态脚本语言,更是对smalltalk不值一提。更是盲目的把会使MFC等同于理解面向对象思想。以为开发出来的程序都是面向对象的。rnrn举个实际的例子来说,我看到很多人都把程序的起始点定位在CView::OnInitialUpdate()或是CDialog::OnInitDialog()中,看到太多了以致我很长一段时间以为逻辑的初始化就是应该放在这里的,等我后来回过头来才知道自己是多么的无知,无知者无畏吧!rnrn从这几年来看,整个中国C++社群[外国的我不清楚,至少CSDN是这样]太关注于语言本身以及一些技术性层次上的问题,被这些给框死了,太多的注意力停留在MFC上了,这个从csdn上VC/MFC的分类也可以看得出rn基础类 | 非技术类 | 界面 | 网络编程 | 进程/线程/DLL | ATL/ActiveX/COM | 数据库 | HTML/XML | 图形处理/算法rn典型的技术型体系,XML这么重要的技术在这个csdn/VC中也体现不出来,发贴回帖的数量少的可怜。rnrn很多现在的问题和几年前的问题还是停留在同一个层次上,相信很多星星级的都会有很大的体会。rn我可以很肯定的说,VC/MFC已经落后了,VC/MFC到底该何去何从这是每一个做VC/MFC都应该思考的一个问题。我们不应该再有那种C++/MFC式的优越感,更多的应该是一种危机感,迫切感。rnrn我相信如果一个热爱java的人来说c++/mfc是怎么怎么烂,我会鄙视他,不理睬他,摆出一副很不屑的态度,然后开始攻击java怎么怎么,效率怎么怎么,但我想我是十分热爱c++/mfc的,我希望和大家坐下来谈谈自己的对vc/mfc的一些想法,对自己的一些展望。不是说说一定要怎么怎么样,就当是朋友聊聊天罢了。rnrnCsdn是伴随我成长起来的地方,从中学到很多知识,结识了很多朋友,人是有感情的,真希望大家都能团结起来,群策群力,从网上到网下,从陌生人到朋友,也许只是一个美好的vision。rnrn未完待续rn 论坛

没有更多推荐了,返回首页