在日常生活中,經常有大量的文本需要處理,正則表達式正是基于此提出的。本文將結合一些具體的實例來解釋它。雖然在不同的語言環境中,正則表達式有不同的語法規則,但其基本語義卻是一致的。http://en.wikipedia.org/wiki/Regular_expression。這將是一個系列教程。本節只是一個開胃菜:)
某一次同學很無聊,然后問我電腦上有無小說。這是顯然的,我是網絡小說迷嘛!從起點down下無數小說存在電腦上,名字都懶得改,都是以數字打頭,然后以“.txt”結尾,比如23432.txt之類的。當然,文件查找還是得用Everything,要不然電腦上的上百萬個文件,手會抽筋的。
(注:我以為Everything是史上最快的文件查找工具,強烈推薦!)
先用"*.txt"嘗試一下,:(,給出一大堆文本文件呀。范圍太廣。還是得用正則表達式來。
^[0-9]*\.txt
Yes!給出了我電腦上存儲的所有小說了。
解釋一下:
^[0-9]表示文件名以0-9之間的數字開頭,^是開頭的意思($結尾)
*表示它前面的字符(這里是數字)要重復若干次(>=0)
\.匹配139869.txt中的那個小數點。因為正則表達式中,‘.’被占用了,表示任意字符,所以要轉義一下
txt,這就不說了,緊接著小數點的是‘txt’三個字符。
Everything只支持部分正則表達式, | () ? * + . [] [^] ^ $ {m,n} 不過已經完全夠用了。
http://xbeta.info/everything/faq.htm#How_do_I_use_regex
考慮這樣一個問題:項目組在驗收的時候,被指出代碼的注釋量不夠,需要達到至少30%才行,也就是至少需要添加6500行注釋。此時老師提出,要將所有的函數加上注釋,函數的名稱、功能、參數、返回值。這個時候,考慮能不能用正則表達式,提取源代碼中的函數信息,然后自動生成注釋模板?比如:
int foo(int x, int y);
替換為:
/**
* @method foo
* @para x
* @para y
* @return
*/
int foo(int x, int y);
注意到,這個函數參數的個數和類型可以是變動的,返回值限定符的個數和類型也是變動的,比如static類型函數,有兩個限定符,而構造函數,則沒有限定符,還有部分virtual類型函數。
本例學習QDialog。預期目的:1. 組織多個窗體。2. 學習Dialog的相關屬性。3. 學習一些widget。
1. 本例中,定義了3個不同的PageWidget,都是從QWidget中派生。用戶在左側list更換后,切換到不同的配置頁。
2. QStackedWidget提供一組widget,但一次只能有一個顯示。將這個widget添加到layout中。
3. 在layout設置中,一般為MainWindow設置一個layout,然后向這個layout中添加不同的widget,layout。
4. 一個窗體是Window或者Dialog,向這個窗體中添加其他的Widget,這些Widget可以使系統提供的,也可以是用戶自己定義的。
5. 本例中使用兩次QListWidget。一次為圖文,一次為文字。setViewMode(),設置ListWidget為圖標模式。通過setIcon(),設置Item的圖標。configButton->setIcon(QIcon(":/images/config.png"));
6. 定義QListWidgetItem的父類為QListWidget,設置QListWidget的項。或者使用addWidget()之類的方法。
7. 左側select切換時,if(!current) current = previous;防止current為0的意外情況。
8. 自定義了一個slot,用來處理contentList被選中項切換時,相應的處理方法。也就是設置stackedWidget的被選中項。通過contentlist的row()確定index,然后設置第index項為當前item。
2008.2.27 by RonLiu
方法一:使用tr()函數
QT中,用QString存儲所有可見得文本/字符串,使用tr()將各種字符編碼的文本轉化為QString,然后既可以將他們設置為控件的顯示文本。
在Widget的構造函數中加入:
QTextCodec::setCodecForTr(QTextCodec::codecForName("gbk"));
QFont font1("Times", 12, QFont::Normal, FALSE);
this->setFont(font1);
這樣在該窗體的其他位置,可以使用tr()設置控件的內容,他們均可以顯示為中文了。
setWindowTitle(tr("消息嗅探器"));
注意:這種方式設置的中文顯示對于整個控件,以及它們的子控件都生效。如果在子控件中另外設置了setFont(),那么全局的字體方案將會失效。
方法二:使用translate()轉換
先將需要顯示的中文轉化為gbk編碼的unicode,然后將unicode轉化為QByteArray,在將只轉化為char指針,并傳遞給translate()函數。
注意:這種方法顯示中文時,會出現失效的情況。譬如在菜單欄中可以顯示中文,但是在Label或者Button中卻無法顯示中文。
另外,這種方法僅僅建議只有少數按鈕顯示中文時選用,否則,代碼寫得也麻煩呀。
如果使用QDesigner生成的ui文件,后創建的界面類,一般都有一個retranslateUI,就是做這個用的。
const char * stringToUnicode(const char *str)
{
static QTextCodec *codec = QTextCodec::codecForName("gbk");
QByteArray qba = (codec->toUnicode(str)).toLocal8Bit();
const char * c_str = qba.data();
return c_str;
}
menuFile->setTitle(QApplication::translate("MainWindow", stringToUnicode("文件"), 0, QApplication::CodecForTr));
QTextCodeC用于在不同的編碼方案之間進行轉換。
方法三:使用Linguist
這是QT自帶的用于軟件本地化的軟件的工具。沒仔細研究過。
這種方式可以用于外文軟件的本地化,那么相比于前兩者方式,處于更高的層次。
延生一:編寫多語言版本的QT程序
(本部分內容參考QT手冊Internationalization一節)
在方法一和方法二種,仍然是一個程序對應一個語言。如果希望QT程序針對不同的語言,有不同的版本,該如何操作?
準備一個.pro文件,如:
HEADERS = funnydialog.h \
wackywidget.h
SOURCES = funnydialog.cpp \
main.cpp \
wackywidget.cpp
FORMS = fancybox.ui
TRANSLATIONS = superapp_dk.ts \
superapp_fi.ts \
superapp_no.ts \
superapp_se.ts
1. 使用lupdate,從QT程序中抽取可轉換的文本,生成一個ts文件。
2. 使用Linguist工具,在原始文本間轉換。ts文件以xml格式保存,可以手動修改。
3. 運行lrelease,生成輕量級的qm格式的消息文件。這種文件可以在程序中使用。
4. In your application, you must QTranslator::load() the translation files appropriate for the user's language, and install them using QCoreApplication::installTranslator().
1. 為什么使用Eclipse進行C++的開發。
因為Eclipse的IDE支持多種語言,如Java、Python、C++,也支持不同的操作系統。這樣不管換到什么環境,或者換一種語言,熟悉的環境不會變化。
2. 安裝和設置Eclipse/CDT的環境。
a. mingw的安裝與配置。http://www.shnenglu.com/romangol/archive/2008/04/19/47595.html。(PATH,C_INCLUDEPATH,CPLUS_INCLUDE_PATH, LIBRARY_PATH)
b. Java虛擬機的安裝與設置。(PATH)
c. Eclipse/CDT的下載與安裝。http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/index.html
3. toolchain設置
新建一個自帶makefile的helloworld程序,build可以通過。但點擊運行時,提示找不到可執行文件。原因在于,新建項目時,沒有選擇合適的toolchain。如果是下載后解壓后得到的CDT,那么toolchain已經內置在其中了。但如果是update的方式獲取,則需要手動下載。
我安裝的是mingw的編譯環境,但選擇cygwin,卻仍然可以生成可執行的程序。奇怪的事情。獲取是因為,設置configuration時,通過檢查環境變量來獲取實際調用的編譯器?
4. 何為toolchain?
A toolchain is a set of tools (such as a compiler, linker, and assembler) intended to build your project. Additional tools, such as a debugger, can be associated with a toolchain. There can be several toolchains available, depending on the compilers installed on your system.
5. 有哪些toolchain可供選擇?
Cygwin,通過支持GNU libc運行庫,它完全實現gun toolchain,使用dll向上提供Windows的兼容層。
mingw。windows平臺下gnu toolchain的入口,它直接使用windows c運行庫,不需要兼容層,但可移植性要差一些。
6. Eclipse如何使用這些toolchain? TODO
The CDT is designed to provide an extensible architecture, that will provide support for integration of tools provided by Independent Software Vendors。
附:
Eclipse 平臺只是用于開發者工具的一個框架,它不直接支持 C/C++;它使用外部插件來提供支持。CDT 是完全用 Java 實現的開放源碼項目(根據 Common Public License 特許的),它作為 Eclipse SDK 平臺的一組插件。這些插件將 C/C++ 透視圖添加到 Eclipse 工作臺(Workbench)中,現在后者可以用許多視圖和向導以及高級編輯和調試支持來支持 C/C++ 開發。
下面是 CDT 插件/組件的完整列表:
對于QT的學習,一直處于半懂不懂的狀態,看文檔也只處于“貌似”的境界,導致真正碰到問題時就個屁掉。這次閱讀basiclayout的demo說明,甚感慚愧,之前學得太膚淺。
1. 設計一個窗體,安排好它的函數和屬性。
2. 基本的layout包括四類,QHBoxLayout,QVBoxLayout,QGridLayout,QFormLayout。前兩個將widget水平或豎直防止,grid將widget以格子的形式放置,formlayout將widget以row的形式放置。
3. layout的使用方法是,先定一個layout,再向這個layout中添加widget,然后使用父類中的setlayout(),設置這個widget的layout。
4. layout有一個setMenubar,可以使得Dialog也可以設置菜單欄。
5. 在定義類時,定義一個enum,之后就可以直接使用這個enum中的元素。
6. QT賦參數的方法為tr("Button %1").arg(i + 1)。
7. QGridLayout有setColumnStretch(int, int)方法,用于設置grid中格子的伸長因子,也就是能夠占用多大的空間。
8. QDialogButtonBox指用于確定/退出的button組。它是這兩類常用button的一個box組合。
9. 本例中涉及到的其它widget包括:
a. QTextEdit,文本編輯框,支持plain text和html text
b. QPushButton,按鈕
c. QGroupBox,將widget以box的形式組織在一起
d. QLineEdit,行編輯框
e. QComboBox,下拉框
f. QSpinBox,spin框,提供數值選擇。
cppblog提供了metablog接口,供用戶使用一些桌面工具操作blog。MetaBlogAPI是一個XML-RPC Service。它可以讓用戶遠程調用Blog程序提供的接口來完成一些功能,比如發布新的文章,查看最新文章的列表等。http://dudu.cnblogs.com/articles/411388.html
先看cppblog的一個接口:
metaWeblog.getCategories()的參數
返回結構體
下面介紹使用Python來操作metablog接口。既然metablog是一個xml-rpc接口,那么就使用Python的xmlrpc庫吧,好消息是這個庫Python已經提供了,就是xmlrpclib。
代碼如下:
import xmlrpclib
user = 'ronliu'
pass = '123'
url = 'http://www.shnenglu.com/ronliu/services/metaweblog.aspx'
server = xmlrpclib.Server(url)
cata = server.metaWeblog.getCategories('', user, pass) #典型的rpc調用
for e in cata:
print e['categoryid'], e['title']
操作結果:
使用xmlrpclib的Server()方法,可以創建一個rpc服務器的代理,然后通過這個代理訪問遠程的方法。可以使用Python提供的調試功能查看rpc的執行過程:
import httplib
httplib.HTTPConnection.debuglevel = 1
使用這些api,即使一個門外漢也可以為自己的網站添加地圖。
下面的代碼,將會創建一個簡單的地圖網頁。如:
<html xmlns=" >
<head runat="server">
<title>地圖測試</title>
<script language="javascript" src="</head>
<body>
<form id="form1" runat="server">
<div id="myMap" style="position:relative; width:400px; height:300px;"></div>
<script language="javascript">
var maps = new LTMaps( "myMap" ); //LTMaps類有一個參數,是該地圖所在div的name
maps.cityNameAndZoom( "beijing" , 5 );
var c = new LTSmallMapControl(); //簡單的放大縮小條
maps.addControl(c);
var point = new LTPoint( 11640969 , 3989945 );//北京
var marker = new LTMarker( point ); //一個標記
maps.addOverLay( marker ); //將標記覆蓋到地圖涂層上
var text = new LTMapText( marker );
text.setLabel( "我的位置" );
maps.addOverLay( text );
</script>
</form>
</body>
</html>
詳細的API說明在http://api.51ditu.com/docs/index.html可以查詢。
51API架構