開源->一步步實現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博客采集工具->詳細設計

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM