好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

一步步实现cnblogs博客采集工具实现主界面布局

一步步实现cnblogs博客采集工具实现主界面布局

欢迎继续关注开源项目CnblogsFan, 如果你是首次看到这个项目,  点击此处 查看有关该项目的详细介绍。

 

  按照项目实现的一般流程, 在对项目完成详细设计后的下一步就是进入编码阶段了。 由于目前依然是一个人在在每天得空闲时间负责这个小项目, 在编码上, wid采用的是由易到难, 逐步深入的方式。 所以, 今天第一步要实现的就是在主界面的布局。

 

在继续阅读以下随笔之前,  你应该具备的知识 :

   1>. Python的基本语法

   2>. 能够使用WxPython创建一个窗口

如果你还没有接触过Python语言并且想要了解它,  点击这里 ;

 

  我们知道, 在WxPython中, 可以使用尺寸器sizer对窗口控件进行智能布局, 这是在WxPython中实现对窗口控件布局管理的常用方法, 但是wid最近在学习C语言Windows程序设计, 不知在这里有没有能够对窗口控件实现智能布局的API, 经过一番考虑后, 所以在这个小项目中, 决定 不使用sizer 对窗口进行智能布局, 而是根据取得上一个控件的 RECT结构 对下一个控件进行布局, 对于这种布局管理,  首先有个弊端, 在进行调整窗口大小时, 窗口中的控件位置以及大小不能根据窗口的大小而变化 , 如果要实现像sizer尺寸器中那样能够根据窗口的大小自动调整控件位置以及大小的话,  可以根据一个wx.SIZE消息来调整控件的大小以及相对坐标 。为了避免将这个弊端体现出来, 所以在窗口的样式上调整为不可调整大小的窗口。

 

声明:  CnblogsFan中所使用的 所有图标文件均来自互联网, 并遵循相关的使用协议, 关于图标的来源记录以及使用协议如下, 如果您也要使用以下图标请认真阅读:

图标来源记录及使用协议
======================

    *该项目中使用的所有图标资源均来自互联网, 通过图标搜索引擎**http://www.easyicon.cn**获取, 图标有关记录如下:   
****** *文件名: CnblogsFan_Spider.png >尺寸: 48x48 >作者: Alessandro Rei >作者网站: http://www.kde-look.org/usermanager/search.php?username=mentalrey >使用协议: GPL ****** *文件名: CnblogsFan_Single.png >尺寸: 48x48 >作者: Oliver Scholtz (and others) >作者网站: http://linux.softpedia.com/developer/Oliver-Scholtz-93.html >使用协议: GPL ****** *文件名: CnblogsFan_Classify.png >尺寸: 48x48 >作者: codefisher >作者网站: http://codefisher.org >使用协议: Creative Commons (Attribution-Noncommercial-Share Alike 3.0 Unported) ****** *文件名: CnblogsFan_Setting.png >尺寸: 48x48 >作者: Pavel InFeRnODeMoN >作者网站: http://www.kde-look.org/usermanager/search.php?username=InFeRnODeMoN >使用协议: GPL ****** *文件名: ICON_CnblogsFan.ico >尺寸: 48x48 >作者: Kyo Tux >作者网站: http://kyo-tux.deviantart.com >使用协议: Creative Commons (Attribution-Noncommercial-Share Alike 3.0 Unported)

 

 

  在对UI设计部分进行介绍之前, 为了能够对设计中提到的各个控件的位置有个大致的把握,  首先预览下该代码在Windows XP下与Linux (Ubuntu)下运行的实际效果图:

一、在Windows XP下运行:

 

 

二、在Linux (Ubuntu)下运行

 

 

 

  接下来开始开始对项目的UI设计部分进行介绍, 采用贴出完整代码的形式, 说明均在注释中。

 #  !/usr/bin/python  
#  coding:utf-8  
#  -------------------------------------------------------------------------------  
#   Name:        CnblogsFan_MainFrame.py  
#   Purpose:  
#
#   Author:      Mr.Wid  
#
#   Created:     13-10-2012  
#   Copyright:   (c) Mr.Wid 2012  
#   Licence:     GNU GPL  
#  ------------------------------------------------------------------------------- 

 import   wx

  class  MainFrame(wx.Frame):               #  从wx.Frame类得到继承 
     def   __init__ (self):                  #  初始化窗口 
        wx.Frame. __init__  (
            self,
            parent  = None,               #  无父窗口 
            title = u '  CnblogsFan  ' ,       #  窗口标题:'CnblogsFan', 
            size = ( ( 900, 600 ) ),     #  窗口大小900x600 
            style = wx.SYSTEM_MENU|wx.CAPTION|wx.MINIMIZE_BOX|wx.CLOSE_BOX       #  带有最小化与最大化按钮的窗口样式 
         )
        self.Center()                                                             #  令窗口在屏幕中居中显示 

         #  -----加载程序图标----- 
        self.AppLogo = wx.Icon( '  src//ICON_CnblogsFan.ico  '  , wx.BITMAP_TYPE_ICO)
        self.SetIcon(self.AppLogo)

          #  -----创建窗口面板----- 
        self.panel =  wx.Panel(self)

          #  -----创建状态栏----- 
        self.userStatus =  self.CreateStatusBar()
        self.userStatus.SetFieldsCount( 4)                    #  将状态栏分为4部分 
        self.userStatus.SetStatusWidths( [-1, -1, -1, -1] )  #  划分比例为4等分 
         #  -- 
         #  状态栏上待显示的文字 
        statusLabel =  [
            u  '   当前状态:  '  ,
            u  '   采集速度:  '  ,
            u  '   采集统计:  '  ,
            u  '   任务统计:  '  ,
        ]
          #  将文字标签显示在状态栏上 
         for  i  in   range( len(statusLabel) ):
            self.userStatus.SetStatusText( statusLabel[i], i )

          #  -----创建菜单栏外框StaticBox-----     #这个StaticBox控件为首个控件 
        self.groupMenuBox =  wx.StaticBox(
            self.panel,
            label  = u '  菜单  '  ,
            pos  = (15, 10),                      #  在首个控件处使用绝对坐标 
            size = (80, 400),                    #  框大小为80x400 
         )
          #  --以下为菜单图标在本地的文件名 
         #  资源文件在src文件夹下, 使用代码示例时请将src资源文件夹与该.py文件放在同一目录 
        self.localImgSrc =  [
              '  CnblogsFan_Spider.png  '  ,
              '  CnblogsFan_Single.png  '  ,
              '  CnblogsFan_Classify.png  '  ,
              '  CnblogsFan_Setting.png  '  ,
              '  CnblogsFan_About.png  '  
        ]
        self.lstMenu  = []                    #  菜单列表, 用来记录菜单按钮控件 
        menuTip =  [
            u  '  采集整个Cnblogs上的随笔.  ' ,       #  当鼠标放在按钮上的相关提示文字 
            u '  采集指定博客上的随笔.  '  ,
            u  '  采集Cnblogs首页分类上的随笔.  '  ,
            u  '  设置软件的相关参数.  '  ,
            u  '  关于CnblogsFan的一些信息.  '  
        ]                                     #  菜单按钮下方的文字说明 
        menuLabel =  [
            u  '  蜘蛛模式  '  ,
            u  '  指定采集  '  ,
            u  '  分类采集  '  ,
            u  '  软件设置  '  ,
            u  '  关于软件  '  
        ]
        rect  = self.groupMenuBox.Rect        #  获取第一个控件self.groupMenuBox的RECT结构 

         #  x, y用来决定菜单按钮的位置 
         #  x = 上个控件的x坐标 + (上个控件的x方向宽度 - 一个按钮的宽度) / 2, 这样按钮控件就能够在groupMenuBox框中居中显示了 
         #  y = 上个控件在y方向上的坐标的三倍 
        x, y = rect[0] + ( rect[2]-48 )/2, rect[1] * 3
         for  i  in  range( len(self.localImgSrc) ):         #  for 循环生成按钮控件 
            tempImg = wx.Image(  '  src//  ' + self.localImgSrc[i], wx.BITMAP_TYPE_ANY )       #  从本地加载图标文件 
            w, h = tempImg.GetSize()                     #  获取加载到的图标尺寸 
            img = tempImg.Scale( w*0.8, h*0.8 )          #  将图像缩放至80% 
            self.lstMenu.append(                         #  创建一个菜单按钮并将其加入到菜单按钮列表中 
                 wx.BitmapButton(
                    self.panel,
                    bitmap  = img.ConvertToBitmap(),      #  将缩放后的按钮图片转换为位图 
                    pos =  ( x, y )
                )
            )
              #  --为每个按钮增加标签 
             wx.StaticText(
                self.panel,
                label  =  menuLabel[i],
                pos  = ( x, y + 50 )                       #  之所以令y再加50是为了能够让每个标签显示在按钮的下方, 而不是上方, 50这个值是经过测量按钮RECT结构的值得到 
             )
            y  += self.lstMenu[i].Rect[0] + 45
             #  --为每个按钮增加按钮提示信息 
             self.lstMenu[i].SetToolTipString(menuTip[i])

          #  在完成一个控件的创建之后下面的创建算法就同上面的了 
         #  ------创建当前采集用户信息栏----- 
        rect = self.groupMenuBox.Rect                    #  获取上一个控件RECT结构 
        self.groupBlogsUserInfoBox =  wx.StaticBox(
            self.panel,
            label  = u '  当前所在博客博主信息  '  ,
            pos  = ( rect[0] + rect[2]+ 20, rect[1 ] ),
            size  = ( 500, 100  )
        )
          #  --用户信息标签 
        adminInfoLabel =  [
            u  '  昵称:  '  ,
            u  '  园龄:  '  ,
            u  '  粉丝:  '  ,
            u  '  关注:  '  ,
            u  '  随笔:  '  ,
            u  '  文章:  '  ,
            u  '  评论:  '  ,
            u  '  地址:  '  
        ]
        self.lstAdminInfo  = []                           #  当前采集用户信息列表 
        rect = self.groupBlogsUserInfoBox.Rect           #  获取self.groupBlogsUserInfoBox的RECT结构 
        x, y = rect[0] + 20, rect[1] + 30
         for  i  in  range(len(adminInfoLabel)):             #  生成标签控件 
            self.lstAdminInfo.append(                    #  将标签控件增添到lstAdminInfo列表当中 
                 wx.StaticText(
                    self.panel,
                    label  =  adminInfoLabel[i],
                    pos  =  ( x, y )
                )
            )
            x  += 150                 #  每个用户信息标签直接间隔150个单位 
             if  x > 450:              #  当放够3个标签后换行放置另外3个标签 
                x = rect[0] + 20 
                y  += 20

         #  -----创建任务控制栏-----                       #用来控制在任务进行中的暂停/停止动作 
        rect =  self.groupBlogsUserInfoBox.Rect
        self.groupControlBox  = wx.StaticBox(             #  创建静态框StaticBox 
             self.panel,
            label  = u '  任务控制  '  ,
            pos  = ( rect[0] + rect[2]+ 20, rect[1] ),    #  位置在当前采集用户的标签的左侧 
            size = ( 230, 100  )
        )
          #  --控制按钮 
        self.btnPauseContinue = wx.Button(               #  创建暂停按钮, 当在任务过程中按下"暂停"后, 暂停标签还要能够变成"继续" 
             self.panel,
            label  = u '  暂停  '  ,
            size  = ( 60, 60 ),                           #  按钮大小 
            pos = ( rect[0] + rect[2]+ 50, rect[1] + 25 )    #  位置 
         )
        self.btnPauseContinue.Disable()                   #  在未进行任务前将按钮设为不可用 
        rect =  self.btnPauseContinue.Rect
        self.btnStop  = wx.Button(                        #  创建"停止"按钮, 用来中途中断任务的进行 
             self.panel,
            label  = u '  停止  '  ,
            size  = ( 60, 60  ),
            pos  = ( rect[0] + rect[2]+ 50, rect[1 ] )
        )
        self.btnStop.Disable()                            #  按钮不可用 

         #  -----成功采集信息栏-----                       #用于输出成功采集到的随笔信息 
        rect =  self.groupBlogsUserInfoBox.Rect
        self.groupSucceedBox  = wx.StaticBox(             #  静态框 
             self.panel,
            label  = u '  成功采集  '  ,
            pos  = ( rect[0], rect[1] + rect[3] + 20  ),
            size  = ( 750, 280  )
        )
          #  --成功采集列表 
        rect =  self.groupSucceedBox.Rect
        self.lstSucceedResults  = wx.ListCtrl(            #  创建成功采集列表框 
             self.panel,
            pos  = ( rect[0] + 10, rect[1] + 20  ),
            style  = wx.LC_REPORT|wx.LC_HRULES| wx.LC_VRULES,
            size  = ( rect[2] - 20, rect[3] - 30  )
        )
        w  = self.lstSucceedResults.Rect[2]               #  获取列表框x方向宽度 
        self.lstSucceedResults.InsertColumn( col = 0, heading = u '  随笔名称  ' , width = w * 0.3 )       #  创建是三个纵列, 分割比例为3:5:1.5, 为了美观留下0.5给竖直滚动条 
        self.lstSucceedResults.InsertColumn( col = 1, heading = u '  来源地址  ' , width = w * 0.5  )
        self.lstSucceedResults.InsertColumn( col  = 2, heading = u '  发布时间  ' , width = w * 0.15  )

           #  用来告知用户当前正在进行的动作 
         #  -----当前动作信息栏----- 
        rect =  self.groupSucceedBox.Rect
        self.groupActionBox  =  wx.StaticBox(
            self.panel,
            label  = u '  当前动作  '  ,
            pos  = ( rect[0], rect[1] + rect[3] + 20  ),
            size  = ( 750, 110  )
        )
          #  --动作输出文本框, 使用文本框进行当前动作输出 
        rect =  self.groupActionBox.Rect
        self.txtFeedback  =  wx.TextCtrl(
            self.panel,
            size  = ( rect[2] - 20, rect[3] - 30  ),
            pos  = ( rect[0] +10, rect[1] + 20  ),
            style  = wx.TE_MULTILINE | wx.TE_READONLY         #  带有竖直方向的滚动条并且将文本框设为只读模式 
         )

          #  在菜单创建栏的下方还剩一个比较小的角落, 用来作为用户反馈意见的位置 
         #  -----意见反馈栏----- 
        rect =  self.groupMenuBox.Rect
        self.groupFeedbackBox  =  wx.StaticBox(
            self.panel,
            label  = u '  告诉作者  '  ,
            pos  = ( rect[0], rect[1] + rect[3] + 20  ),
            size  = ( rect[2], 110  ),
        )
          #  --创建意见输入文本框 
        rect =  self.groupFeedbackBox.Rect
        self.txtFeedback  =  wx.TextCtrl(
            self.panel,
            size  = ( rect[2] - 10, rect[3] - 50  ),
            pos  = ( rect[0] + 5, rect[1] + 20  ),
            style  =  wx.TE_MULTILINE
        )
          #  --创建提交按钮 
        self.txtFeedback.SetMaxLength(1024 )
        rect  =  self.txtFeedback.Rect
        self.btnFeedback  =  wx.Button(
            self.panel,
            label  = u '  提交  '  ,
            pos  = ( rect[0], rect[1] + rect[3] + 5  ),
            size  = (rect[2], 20 )
        )


  def   test():
    cnblogsFan  =  wx.PySimpleApp()
    mainFrame  =  MainFrame()
    mainFrame.Show()
    cnblogsFan.MainLoop()

  if   __name__  ==  '  __main__  '  :
    test() 

所有项目文件均在GitHub上, 项目地址:    https://github.com/mrwid/CnblogsFan

----- ----- ----- -----

说明: 这里仅仅是实现了主界面的相关布局, 对于相关的采集参数设置对话框, 软件设置对话框、关于软件对话框等相关的窗口的创建过程下次就不再往首页上推了, 创建的过程都是差不多, 只是将这里的从wx.Frame类中继承改为从wx.Dialog类中得到继承, 其他也就是往客户区放相关的控件, 没什么可叙述的。最新的项目进展欢迎关注wid的博客, 或者从GitHub上获得最新的项目代码。

 

wid, 2012.10.15

 

上一篇:  开源->一步步实现cnblogs博客采集工具->详细设计  

 

 

分类:  开源项目案例分析

标签:  开源 ,  CnblogsFan ,  项目案例分析

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于一步步实现cnblogs博客采集工具实现主界面布局的详细内容...

  阅读:38次