21:00 < xyzghost> 圖 21:00 < xyzghost> 在那呢 21:00 <@jesse_> 時間到了, 要開始囉! 21:00 <@lloyd_> 拍手.. 21:00 <@jesse_> xyzghost: 等一下會有 URL 21:00 < xyzghost> OK 21:00 <@jesse_> 拍手... 21:01 < xyzghost> 拍手.... 21:01 < xyzghost> 呵 21:01 * jesse_ 拍拍拍 21:01 < spke> 九點了...加油加油 . 21:01 * AceLan 鼓掌喝采! 21:01 < kanru> 拍拍拍拍 21:01 <@jesse_> 很高興這次請到 AceLan 上來 21:01 /*/ [In] anychris (any@sw70-158-77.adsl.seed.net.tw) has joined #debian.tw 21:01 <@AceLan> ccc 21:01 <@jesse_> 講 Qt 程式設計無痛起步 21:02 <@jesse_> 我廢話不多說, 請 AceLan 開始囉! 21:02 <@AceLan> ^^ 21:03 <@AceLan> 大家好,這次要講的題目是 "Qt 程式設計無痛起步"。 21:03 <@AceLan> 相信大家都已經裝好所需的程式, 如果還沒裝好的話,趁我現在還在廢話的時後 apt-get 一下吧 ^^ 21:03 <@AceLan> 由於這是無痛起步,所以我不會講太多跟程式相關的東西,我會盡量使用 Qt 提供的 widget 來組合出程式,但是還是難免會需要寫些程式碼,請各位多多包含 m(_ _)m 21:04 <@AceLan> 在開始之前,我先提一下我們可能會使用到的一些程式方面的技術,包括 C++、物件導向概念、STL…等。沒蓋念沒關係,用到的東西都很簡單,要是真的聽不懂,請問 google 大大 :p 21:04 <@AceLan> 趁大家還在裝 Qt lib 的時間,我來貼點明哲大大之前寫的文章,稍微簡介一下 Qt,由於 21:04 <@AceLan> 當時時空背景的關係,gtk 還不成氣候,所以請某位 gnome 派的大大稍微忍耐一下 :p 21:04 * AceLan 刀疤蔡竟然不在 :( 21:04 <@AceLan> [Quote] 21:04 <@AceLan> What is Qt ? 21:05 <@AceLan> 在現有的window system ,如 MS Window, X Window ,Mac 等的操作上,都提供一些常見的 21:05 <@AceLan> 視窗元件如 Button,Toolbar, Scrollbar 方便使用者操作, Qt 就是一套這樣的 library 21:05 <@AceLan> ,它除了提供一些常見的視窗元件外,還有提供類似 STL 的 abstract data type,並且整 21:05 <@AceLan> 合 BSD socket ,I/O control, 及一些在視窗程式設計上常見的功能,你可以把它視為一種提供與MFC,OWL 這些 library 相似功能的 library。 21:05 <@AceLan> 除此之外, Qt 還是一套跨平台的 GUI (Graphic User Interface ) library ,除了有 API layer 的相容外也提供GUI介面的模擬。例如在麥金塔上,你可以使用 Mac Style 的GUI 介面,免除使用者重新學習一個新的操作介面。 21:06 <@AceLan> 目前 Qt 最常使用的地方還是在 X Window 上,因為 X Window 本身在設計上只有提供一個 window system 所需的最基本功能,如畫線,設定視窗顏色,設定每個 pixel 的值等。所以像 Qt 這些提供較高階視窗操作的 21:06 <@AceLan> library 就很流行,加上目前有許多大型的計畫如 KDE , KDevelop 等都採用 Qt 作為內定的 GUI library 使得 Qt 在 X Window 上儼然有主流 GUI library 的姿態。 21:06 /*/ [In] asho (~asho@218-168-24-82.HINET-IP.hinet.net) has joined #debian.tw 21:06 <@AceLan> 那 Qt 與其他 widgets set (這類 GUI library 在 X Window 上稱為 Widget Set,同理 21:06 <@AceLan> widget 就是指那些視窗元件如 Scrollbar 等)比起來,除了上面所講的跨平台外有何特 21:06 <@AceLan> 別的地方: 21:07 <@AceLan> * 使用 C++ :可以利用 C++ 本身在 C++ 語法上的支援,及與現有的 c library 相容,這點在慣用 MS Windows 上的人看起來可能覺得沒什麼,可是在 Unix/X 上的環境相當複雜,有各種不同的 language ,依不同場合及需求同時使用,不像 Windows 上就那幾套工具及 library 。 21:07 <@AceLan> * 與 OpenGL 整合在一起,提供完整 2D/3D 的繪圖。 21:08 <@AceLan> * 提供幾乎與 stand c++ library 相容的 library ,如 QTL ,File I/O,network , compress ,composed graphic...,所以你的 Qt application 幾乎 只要重新 compile 就可在其他 platform 上跑。 21:08 <@AceLan> * 提供 signal/slot,作為 object 之間溝通的基本方式,這也是這裡所要講的重點,我們後面再做詳細的討論。 21:08 <@AceLan> [/Quote] 21:08 <@AceLan> 好了,廢話完了,現在開始用 Qt Designer 來寫個 Hello World 程式,順便測試一下各位的 Qt 是否有安裝正確。 21:09 <@AceLan> 首先,請大家開啟 Qt Designer,在 console 下輸入 designer 或 designer-qt3 或是在 K 選單中 程式開發->Qt Designer 或是跟我一樣用 CVS 版的 21:09 <@AceLan> KDE 可在 K 選單->Unknown->Qt Designer 開啟,開啟來的 Qt Designer 長的像這樣 http://kde.linux.org.tw/~acelan/irc_conference/qt01.png 21:09 -cancan:#debian.tw- 116: http://kde.linux.org.tw/~acelan/irc_conference/qt01.png from AceLan 21:10 /*/ [Out] asho (~asho@218-168-24-82.HINET-IP.hinet.net) has quit [Client exiting] 21:10 <@jesse_> http://gallery.debian.org.tw/20031018/qt01 21:10 -cancan:#debian.tw- 117: http://gallery.debian.org.tw/20031018/qt01 from jesse_ 21:10 <@AceLan> 問一下 有都開起來了嗎 21:10 <@jesse_> cancan: part 21:10 /*/ [Out] cancan was kicked from #debian.tw by jesse_ [jesse_] 21:11 <@AceLan> 我們選擇 C++ Project 來建立一個新的 project(http://kde.linux.org.tw/~acelan/irc_conference/qt02.png) 21:11 < kanru> 有^^ 21:11 <@AceLan> ^^ 21:11 <@jesse_> http://gallery.debian.org.tw/20031018/qt02 21:12 /*/ [In] xpalex (~blahwins@210-85-211-15.cm.apol.com.tw) has joined #debian.tw 21:12 <@AceLan> 在 Settings tab 的 Porject File 那,請設定好 project 的路徑,以免檔案太凌亂,然 21:12 <@AceLan> 後選擇 C++ tab,看一下你所安裝的 Qt 有沒有 -mt 字樣,這是 multi-thread 版的 Qt lib,如果有的話,請在 Config 那加上 thread(http://kde.linux.org.tw/~acelan/irc_conference/qt03.png),然後就可以建立 project 了。 21:12 <@jesse_> http://gallery.debian.org.tw/20031018/qt03 21:13 <@AceLan> 建立好 project 之後,我們還得要 new 一個 dialog,所以 File->New 選 Dialog,注意 21:13 <@AceLan> 上方的 Insert into 是否是你 project 的名稱。new 完之後你就有個 dialog 可以在上面放東西了。 21:14 <@AceLan> 首先我們先在左邊的 Toolbox 選擇 Common Widget 的 TextLabel,然後在 dialog 上隨意的拉出一塊方形的區域,然後再到 Common Widget 裡選擇 PushButton,一樣在 dialog 上隨意拉出區域(http://kde.linux.org.tw/~acelan/irc_conference/qt04.png) 21:14 <@jesse_> http://gallery.debian.org.tw/20031018/qt04 21:14 <@AceLan> 然後我們在 textLabel1 上點兩下,來改一下它顯示的內容,把它改成 "Hello Wolrd!!" 21:15 <@AceLan> 接著一樣在 pushButton1 點兩下,將內容改成 "離開" 或是 "再見" 隨你高興。 21:15 <@AceLan> 最後,我們看上面的那個 Form1 字樣很不滿意,所以我們先在 dialog 上點一下,然後到右下角 Property Editor/Signal Handler 的 Property Editor tab 那邊去找到 caption 這個欄位,將它改成 "Hello",完成的 dialog 就會長成這樣 http://kde.linux.org.tw/~acelan/irc_conference/qt05.png。 21:15 <@jesse_> http://gallery.debian.org.tw/20031018/qt05 21:16 <@AceLan> 完成了畫面,可以從 Preview->Preview Form 或是按下 C-t 可以看到畫面執行時的樣子。 21:16 <@AceLan> 這樣會太快嗎? 21:17 <@jesse_> 好像有一點點.. :) 21:17 <@kevinwatt> 光用眼精看的話不會.. :P 21:17 <@AceLan> :p 21:17 <@AceLan> 那我在慢一點 大家慢慢來喔 21:18 * AceLan 揉了揉 zzz 的雙眼, 打了個呵欠, 愛睏ㄍㄚˋ. 21:18 <@jesse_> @@ 21:18 * AceLan 用很奇怪的眼神瞄 jesse_。 21:19 <@jesse_> 繼續吧! :) 21:19 <@AceLan> 到這邊有人有什麼問題嗎 21:19 < xyzghost> #_# 21:19 < anychris> 可以在兩句話之間空一行嗎 這樣應該會清楚點@@ 21:19 <@AceLan> 是的 21:19 <@AceLan> 21:20 <@AceLan> 這樣可以嗎 :p 21:20 /*/ [In] descent (a@u248-157.u61-71.giga.net.tw) has joined #debian.tw 21:20 < jrgl> 沒問題... :-) 21:20 * AceLan 貪婪地舔了舔 descent 的臉。 21:20 < anychris> 嗯:) 21:20 < xyzghost> ......... 21:20 <@AceLan> 那我要繼續囉 21:20 <@AceLan> 接著我們要來加點程式,讓那個"離開"按鈕生效。 21:20 <@AceLan> 21:20 <@AceLan> 點一下"離開"按鈕,然後到右下的 Property Editor/Signal Handler 的 Signal Handler tab 上的 clieked() 點三下 21:21 <@AceLan> 21:21 <@AceLan> 它會跳出一個對話盒,詢問你是否要建立 .ui file,回答 Yes 21:21 <@AceLan> 21:21 <@AceLan> 後你會看到一個編輯程式的畫面,在大括號裡面輸入 this->reject(); 21:22 <@AceLan> 21:22 <@AceLan> 這行的意思是說,呼叫 this 這個物件的 reject() method,this 就是我們的 dialog,而 reject() 的意思就是關閉 dialog (http://kde.linux.org.tw/~acelan/irc_conference/qt06.png)。 21:22 <@jesse_> http://gallery.debian.org.tw/20031018/qt06 21:22 <@AceLan> 21:23 <@AceLan> 存檔完後,選有一個步驟要做,那就是建立 main() function。 21:23 <@AceLan> 21:23 /*/ [Out] descent (a@u248-157.u61-71.giga.net.tw) has quit [Leaving] 21:23 <@AceLan> File->New 選 C++ Main-File(main.cpp),確定有 include Form1 之後按確定,然後就可以看到 main.cpp 的程式編輯畫面,直接存檔就可以了。 21:23 /*/ [In] descent (a@u248-157.u61-71.giga.net.tw) has joined #debian.tw 21:23 <@AceLan> 21:23 <@AceLan> 接著,我們要來編譯程式了。 21:23 <@AceLan> 21:24 <@AceLan> 開啟 console 切換到 project 的 hello 目錄,確定 QTDIR 有正確指到 Qt 的目錄,我的設定是 export QTDIR=/usr/share/qt3/ 21:24 <@AceLan> 21:24 <@AceLan> 然後輸入 qmake hello.pro 21:24 <@AceLan> 21:25 <@AceLan> 它會幫我們產生 Makefile 檔,接著再執行 make 就可以產生出我們的 hello 程式了。(http://kde.linux.org.tw/~acelan/irc_conference/qt07.png) 21:25 <@jesse_> http://gallery.debian.org.tw/20031018/qt07 21:25 /*/ [Out] descent (a@u248-157.u61-71.giga.net.tw) has quit [Leaving] 21:25 <@AceLan> 21:25 <@AceLan> 呼呼~~ 終於完成了 hello 程式,到這邊有什麼問題嗎。 21:25 /*/ [In] descent (~a@u248-157.u61-71.giga.net.tw) has joined #debian.tw 21:25 < descent> testing 21:25 < descent> 測試 21:25 <@jesse_> AceLan: dialog 是指這個程式嗎? 21:26 <@AceLan> jesse_: 21:26 <@AceLan> jesse_: 是的 21:26 <@jesse_> this->reject() 的 this 不是指該 button ? 21:26 <@AceLan> jesse_: 因為這個 hello 是以 dialog 為主體 所以用 dialog 來稱呼 21:27 <@AceLan> 不的 this 指的是 dialog 21:27 <@AceLan> button clicked 之後 dialog 要關閉 呼叫的當然是 dialog 的 reject() 21:27 <@jesse_> oh, Form1::pushButton ... 21:28 <@jesse_> ok 21:28 <@AceLan> ^^ 21:28 /*/ [Out] xpalex (~blahwins@210-85-211-15.cm.apol.com.tw) has quit [Leaving] 21:29 <@AceLan> 有人的 hello 成功了嗎 21:29 < kanru> 沒QQ 21:29 <@AceLan> 是什麼問題呢? 21:29 < jrgl> 成功了...:-) 21:29 <@AceLan> jrgl: 恭喜 ^^ 21:29 < kanru> .h檔找不到 21:30 <@AceLan> kanru: echo $QTDIR 21:30 <@AceLan> kanru: 看一下你的設定對嗎 21:30 < kanru> 我的應該是在/usr/include/qt3 21:31 <@AceLan> kanru: 那你試試 export QTDIR=/usr/include/qt3 之後在 make 試試 21:31 < anychris> 有其他人是使用windows的嗎.. 21:31 <@AceLan> anychris: 你是用 windows? 21:31 < anychris> 嗯..我右邊是空的 找不到 Property Editor/Signal Handler 21:32 <@AceLan> anychris: windows->views 那邊可以點出來 21:32 < kanru> 我設了以後make...結果還是g++ -c -pipe -Wall -W -O2 -DQT_NO_DEBUG -I/usr/share/qt3/mkspecs/default -I. -I/usr/share/qt3/include -I.ui/ -I. -I.moc/ -o .obj/main.o main.cpp 21:33 <@AceLan> 錯誤訊息是? 21:33 < kanru> main.cpp:1:26: qapplication.h: 沒有此一檔案或目錄 21:33 < kanru> 等等 21:33 < kanru> 都是這樣的錯誤 21:33 <@AceLan> kanru: 你是用 debian 嗎? 21:33 < anychris> AceLan: 我是有 Property View.. 不過找不到 Signal Handler 21:34 < kanru> AceLan:yes 21:34 <@AceLan> anychris: 同一個窗 但是不同 tab 21:34 <@AceLan> kanru: 那你的設定應該跟我一樣才對阿 21:34 <@AceLan> kanru: export QTDIR=/usr/share/qt3 21:34 < anychris> AceLan: 該怎麼說呢.. 我的 property view沒tab 21:35 <@AceLan> anychris: 你是用 windows? Qt 2.3? 21:35 < kanru> AceLan:還是一樣...我覺得他好像還是沒改路徑 21:36 < anychris> AceLan: 嗯, QT Designer 2.3.0 21:36 <@AceLan> anychris: Qt 2.3 的 designer 沒辦法在上面編 code 21:36 <@AceLan> anychris: 只能拉畫面而已 *_* 21:36 < anychris> AceLan: @@ 21:37 <@AceLan> kanru: hmm 21:38 < anychris> AceLan: 那麼win32下還有其他能code qt的軟體嗎.. 難怪我之前玩的時候就找不到寫code的部份.. 21:38 < kanru> AceLan:我用locate找...qapplication.h是放在/usr/lib/qt3下耶 21:38 <@AceLan> kanru: export 完之後 重新 qmake 一次 21:38 < kanru> 錯..是/usr/include/qt3 21:39 <@AceLan> anychris: 好像沒有耶 Qt 2.3 就是只能拉畫面 拉完之後在自己用其他的 editor 寫程式 21:39 <@AceLan> kanru: 很多目錄都可以 但是 /usr/share/qt3 裡面是比較完整的 21:40 <@AceLan> kanru: 不單單只有 header 還有 uic moc 等程式也在裡面 21:41 < R7chars> mm, bcbx /kylix? 21:41 <@AceLan> anychris: 等一下我會講手動編譯程式的方法 你可能會用到那部份 21:42 < anychris> AceLan: 嗯 :) 21:42 < kanru> 會不會是因為我沒有裝qt3-apps-dev的關係? 21:42 <@AceLan> kanru: 你裝看看吧 :p 21:42 /*/ [In] acechen (~acechen@circ.tcfsh.tc.edu.tw) has joined #debian.tw 21:43 < kanru> q 21:43 /*/ [Out] kanru (~kanru@ip097.puli18.ncnu.edu.tw) has quit [[BX] Pretzel Boy uses BitchX. Shouldn't you?] 21:44 /*/ [In] kanru (~kanru@ip097.puli18.ncnu.edu.tw) has joined #debian.tw 21:44 < kanru> QQ 21:44 <@AceLan> 由於時間的關係 我們要繼續往下講了 21:44 < anychris> AceLan: 請問qt designer win32下是都沒有辦法在designer下code? 還是只有non-commercial沒有? 21:44 <@AceLan> kanru: 你成功了嗎? 21:45 < kanru> AceLan:沒...我等等再試? 21:45 <@AceLan> anychris: non-commercial 只有 2.3 版 要 3.0 以上才能在 designer 裡面寫 code 21:45 <@AceLan> kanru: ^^ 21:46 <@AceLan> 那我要繼續囉 21:46 <@AceLan> 現在來講一下剛剛使用的 Qt 提供的編譯工具。 21:46 <@AceLan> 21:46 <@AceLan> qmake 可以從 Qt Designer 的 project 檔生出 Makefile 檔 21:46 <@AceLan> Makefile 檔裡頭會有 uic、moc 等 qt 的 preprocessor 來幫你將在 Qt Designer 上拉的畫面轉成 C++ 的 class。 21:47 <@AceLan> 21:47 <@AceLan> uic 的主要工能是將 .ui 檔轉成包含 widgets 的 .h 與 .cpp,裡面會有 dialog 上 widgets 的 constructor,還有那些 button clicked 之後會觸發的程式碼。 21:47 <@AceLan> 21:47 <@AceLan> 而 moc 則是將這些轉換後的程式碼裡面有用到的 Qt 特有的東西再經過一次處理。 21:47 <@AceLan> 21:47 <@AceLan> 因為現在 qmake 功能強大,以經不需要手動來執行 uic、moc 這些程式了,不過我們還是以剛剛的 hello 為例,說明一下不使用 qmake 來幫我產生 Makefile 檔時,我們所需要的步驟。 21:47 <@AceLan> 21:48 <@AceLan> 首先先來看一下我們目前的目錄結構 等一下提到的檔案路徑就以這個為準 21:48 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/hello$ ls -a 21:48 <@AceLan> . form1.ui hello main.cpp .moc .ui 21:48 <@AceLan> .. form1.ui.h hello.pro Makefile .obj 21:48 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/hello$ ls .moc 21:48 <@AceLan> moc_form1.cpp 21:48 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/hello$ ls .ui 21:48 <@AceLan> form1.cpp form1.h 21:48 <@AceLan> 21:48 <@AceLan> 執行 uic 來將 .ui 檔成 class 及其 constructor 21:48 <@AceLan> uic form1.ui > .ui/form1.h # 產生 header -- class 的定義 21:48 <@AceLan> uic -impl .ui/form1.h form1.ui > .ui/form1.cpp # 產生 constructor 及在 Qt Designer 中寫的程式碼 21:48 <@AceLan> 21:49 <@AceLan> moc .ui/form1.h > .moc/moc_form1.cpp # 將 .ui/form1.h 中用到的 Qt 特有的 macro 作處理 21:49 <@AceLan> g++ -o hello .ui/form1.cpp .moc/moc_form1.cpp main.cpp -I/usr/share/qt3/include -I.ui -lqt-mt # 編譯程式 21:49 <@AceLan> 21:49 /*/ [Out] anychris (any@sw70-158-77.adsl.seed.net.tw) has quit [Ping timeout] 21:50 <@AceLan> 以上就是自己動手編譯程式所需的步驟。對於這些工具有什麼問題嗎? 21:51 < jrgl> AceLan: 沒有....:) 21:51 <@AceLan> ^^ 21:51 < kanru> AceLan:有...我沒有/usr/share/qt3/include...是不是少裝了什麼? 21:52 < jrgl> usr/share/qt3/include libdevel/libqt3-dev,libdevel/libqt3-mt-dev 21:52 <@AceLan> 呵呵 動作比我快 21:52 /*/ [In] anychris (any@sw68-104-104.adsl.seed.net.tw) has joined #debian.tw 21:53 <@AceLan> kanru: ok 了嗎? 21:54 <@AceLan> 後面一一堆廢話 還有時間讓你慢慢試 21:54 <@AceLan> 我先把他貼完喔 :p 21:54 < kanru> k 21:54 <@AceLan> 再來要講解 widget 21:54 <@AceLan> 21:54 <@AceLan> widget 就是指構成視窗畫面的元件,像是 scrollbar、texteditor、combobox、pushbutton…等等 21:54 <@AceLan> 21:54 <@AceLan> 就是在 Qt Designer 左手邊那欄整個都是,那些就是 widget 啦。 21:54 <@AceLan> 21:55 <@AceLan> 關於 widget 的其他介紹,我想請各位到這個網站看就可以了,讓我偷懶一下吧 :p 21:55 <@AceLan> 21:55 <@AceLan> http://www.caterpillar.onlyfun.net/phpBB2/viewforum.php?f=15 21:55 <@AceLan> 21:55 <@AceLan> 裡面有很多 widget 的使用範例,有需要的話到這邊看一下用法是最方便的。不過他的頻寬不大,大家一起進去看的話,可能會動不了喔 :p 21:55 <@AceLan> 21:55 <@AceLan> 關於 signal/slot 機制的說明,也請大家來看這篇明哲大大的文章,再讓我偷懶一下吧 :p 21:55 <@AceLan> 21:55 <@AceLan> http://www.linuxfab.com/indexColumnDataFriendlyPrint.php?CID=33 21:56 <@AceLan> 21:56 <@AceLan> signal/slot 的內容在那篇文章大約 1/3 的地方(The Signal/Slot Method),從那邊開始看就可以了。 21:56 <@AceLan> 21:56 <@AceLan> 休息三分鐘讓各位消化一下 ^^ 21:59 /*/ [In] saviro (~Saviro@pc9.cable68.tku.edu.tw) has joined #debian.tw 22:00 <@AceLan> 那我們要繼續囉 22:00 <@AceLan> 22:00 <@AceLan> 剛剛 hello 程式的版面沒有經過排版,而且我們縮放視窗時,widget 也不會跟著改變相對位置,所以我們現在要來加上 widget 的 layout,好讓他能在 user 縮放視窗時也可以運作正確。 22:00 <@AceLan> 22:01 <@AceLan> 再將 hello project 在 Qt Designer 中開起來,如果你的視窗沒出現任何東西的話,請選擇 Window->Views->Project Overview 然後將 form1.ui 給點出來,然後再將 Porject Overview 給關掉。 22:01 <@AceLan> 22:01 <@AceLan> 首先我們要先想好我們希望 widget 的擺放方式,我們想要那個 textLabel 在上面,pushButton 在右下角 22:01 <@AceLan> 22:02 <@AceLan> 所以我們選擇彈簧(spacer)(我自己亂叫的 :p)在 pushButton 的左側橫拉(http://kde.linux.org.tw/~acelan/irc_conference/qt08.png) 22:02 <@jesse_> http://gallery.debian.org.tw/20031018/qt08 22:02 <@AceLan> 22:02 <@AceLan> 然後將 spacer 跟 pushButton 兩個一起框起來,並且選擇這個(http://kde.linux.org.tw/~acelan/irc_conference/qt09.png) 22:02 <@AceLan> 22:02 <@jesse_> http://gallery.debian.org.tw/20031018/qt09 22:03 <@AceLan> 22:03 <@AceLan> 表示 spacer 跟 pushButton 兩個是橫向並排的(http://kde.linux.org.tw/~acelan/irc_conference/qt10.png) 22:03 <@jesse_> http://gallery.debian.org.tw/20031018/qt10 22:03 <@AceLan> 22:03 <@AceLan> 然後兩將 textLabel 跟 spacer & pushButton 一起框起來,選擇這個(http://kde.linux.org.tw/~acelan/irc_conference/qt11.png) 22:04 <@jesse_> http://gallery.debian.org.tw/20031018/qt11 22:04 <@AceLan> 22:04 <@AceLan> 表示他們是縱向直排的(http://kde.linux.org.tw/~acelan/irc_conference/qt12.png) 22:04 <@jesse_> http://gallery.debian.org.tw/20031018/qt12 22:04 <@AceLan> 22:04 <@AceLan> 最後,是不是還覺得 dialog 內容跟外框不搭呢?我們直接點 dialog 一下,然後再選直排或橫排一下(執行結果沒有差別) 22:05 <@AceLan> 22:05 <@AceLan> 這樣內容跟外框就合起來了,順便再調整一下 dialog 大小(http://kde.linux.org.tw/~acelan/irc_conference/qt13.png)。 22:05 <@jesse_> http://gallery.debian.org.tw/20031018/qt13 22:05 <@AceLan> 22:05 <@AceLan> 存檔之後照剛剛的編譯步驟再編一次,就可以看到怎麼縮放都正常的 hello 了。 22:05 <@AceLan> 22:06 <@AceLan> 以上的步驟在給各位三分鐘練習 22:06 /*/ [Out] acechen (~acechen@circ.tcfsh.tc.edu.tw) has left #debian.tw [acechen] 22:09 <@AceLan> 插撥一下 -- 蔡豐安再見安打 兄弟象封王 三連霸!!!!!!!!! 22:09 < anychris> AceLan: ..= = 22:09 < saviro> .............. 22:09 <@AceLan> 各位都不是象迷阿 :p 22:09 < anychris> AceLan: 題外話..我比較在意古巴那邊的情形:) 22:10 < jrgl> AceLan: 打完啦...:-) 22:10 < saviro> 古巴怎麼了 22:10 <@AceLan> anychris: 二連勝了 還有兩場可以進八強 22:10 <@AceLan> 好啦 我們繼續吧 :p 22:10 < anychris> AceLan: 嗯..不過要接下來兩場都贏.. 22:11 <@AceLan> 22:11 <@AceLan> Qt 雖然提供了很多好用的 class,但是有時後我們還是需要稍微增加些東西到物件中,或是改變 Qt 物件的行為,這時後我們得要自行另外撰寫程式。 22:11 <@AceLan> 22:11 <@AceLan> 這個我們使用 hacker language translator 這個程式來當作範例。 22:11 <@AceLan> 22:12 <@AceLan> 我先簡介一下這個程式是在做什麼的,他是用來將英文轉成駭客語言的,沒看過駭客語言的可以到 google 選一下語系介面,選駭客,就可以看到這樣的畫面(http://www.google.com/intl/xx-hacker/) 22:12 <@AceLan> 22:12 <@AceLan> 我們準備用一些簡單的規則來將英文轉成駭客語。規則是這樣的: 22:12 /*/ [Out] descent (~a@u248-157.u61-71.giga.net.tw) has quit [Connection reset by peer] 22:12 <@AceLan> o -> 0 22:12 <@AceLan> l -> 1 22:12 <@AceLan> z -> 2 22:12 <@AceLan> e -> 3 22:12 <@AceLan> a -> 4 22:12 <@AceLan> s -> 5 22:12 <@AceLan> g -> 6, 9 22:12 /*/ [In] descent (a@u248-157.u61-71.giga.net.tw) has joined #debian.tw 22:12 <@AceLan> t -> 7 22:13 <@AceLan> b -> 8 22:13 <@AceLan> o -> 0 22:13 <@AceLan> l -> 1 22:13 <@AceLan> z -> 2 22:13 <@AceLan> e -> 3 22:13 <@AceLan> a -> 4 22:13 <@AceLan> s -> 5 22:13 <@AceLan> g -> 6, 9 22:13 <@AceLan> t -> 7 22:13 <@AceLan> b -> 8 22:13 <@AceLan> 22:13 <@AceLan> 當然,這不是全部的規則,我們只是舉幾個規則當例子而已。 22:13 <@AceLan> 22:13 <@AceLan> 我們預設的畫面長這樣 http://kde.linux.org.tw/~acelan/irc_conference/qt14.png 22:14 * AceLan 用很奇怪的眼神瞄 jesse_。 22:14 <@jesse_> http://gallery.debian.org.tw/20031018/qt14 22:14 <@AceLan> ccc 22:14 <@AceLan> 22:14 <@AceLan> 上面是正常的英文,當使用者 22:14 <@AceLan> 輸入完之後按下 enter,下方就會出現翻譯好的 hacker 文。 22:14 <@AceLan> 22:14 <@AceLan> 畫面上的元件有兩個 groupbox,裡面各包了一個 textedit(textEdit1、textEdit2),下方有一個 pushbutton(pbExit),就這樣而已,經過之前的講解,大家應該可以自行將這個畫面拉出來吧 ^^ 22:14 <@AceLan> 22:15 <@AceLan> 請大家動手拉一下畫面吧 ^^ 22:15 <@AceLan> 一樣 三分鐘 ^^ 22:16 < kanru> AceLan:libqt3-mt-dev跟我的xfree4.3沖到...QQ 22:16 < jrgl> AceLan: 請問什麼是駭客語言? 22:16 <@AceLan> @_@ 22:17 < saviro> 還真的沒聽過 22:17 <@csardas> 哈 22:17 <@AceLan> jrgl: google 的語系有可以選 22:17 <@AceLan> 其實是搞怪語言啦 :p 22:17 < kanru> AceLan:沒法玩嚕...只好用看的..哈 22:17 < jrgl> AceLan: google還有克林貢語...@@ 22:18 < jrgl> AceLan: 是誰搞出來的阿? 22:18 <@AceLan> kanru: 應該不會這樣吧 還是你試試 libqt3-dev 22:18 <@AceLan> jrgl: 不是我 *_* 22:19 <@AceLan> 那我要繼續囉 22:19 <@AceLan> 22:19 < kanru> AceLan:因為會用到xlib-pic_4.2 22:19 <@AceLan> hmm 22:20 <@AceLan> kanru: 那你先看好了 對話會有紀錄 到時在操作看看 22:20 <@AceLan> 22:20 <@AceLan> 拉好之後,我們要使用一個簡單的 signal/slot 來讓輸入的英文(textEdit1)自動顯示到 hacker 那邊(textEdit2)。 22:20 <@AceLan> 22:20 <@AceLan> 先選擇 textEdit1,然後選擇 Property Editor/Signal Handler 的 Signal Handler tab 上的 clieked() 點三下,還有 Exit 按鈕的 clicked(),加入如下的程式 22:20 <@AceLan> void Form1::textEdit1_returnPressed() 22:20 <@AceLan> { 22:20 <@AceLan> textEdit2->setText( textEdit1->text()); } 22:20 <@AceLan> void Form1::pbExit_clicked() 22:20 <@AceLan> { 22:21 <@AceLan> this->reject(); 22:21 <@AceLan> } 22:21 <@AceLan> 22:21 <@AceLan> 然後再 new 一個 main() 之後,就可以試著去編譯看看,看看在 English 那邊輸入完之後按 enter,字會不會也出現在 Hacker 那邊(http://kde.linux.org.tw/~acelan/irc_conference/qt15.png)。 22:21 <@jesse_> http://gallery.debian.org.tw/20031018/qt15 22:21 <@AceLan> 22:22 * AceLan 突然發現 這個沒用到 signal/slot :p 22:22 <@jesse_> @_@ 22:22 * AceLan 噓~~ 22:22 < saviro> TT 22:22 <@AceLan> 22:22 < jrgl> @_@ 22:22 <@AceLan> 現在我們要進入重頭戲加入自己的程式碼了。 22:23 <@AceLan> 22:23 <@AceLan> 我的構想是這樣的,取得 textEdit1->text() 的值,然後將值傳給我們自己寫的物件,經過轉換之後再將值傳給 textEdit2->setText()。 22:23 <@AceLan> 22:23 <@AceLan> 但是由於所有的 .cpp .h 檔都是由 uic、moc 自動產生的,所以我們不能直接去修改那些程式,或是直接加入我們的 class 進去 22:24 <@AceLan> 22:24 <@AceLan> 所以我們要再建立一個目錄 src/ 建立一個 h4x37.cpp,建立 include/ 建立一個 h4x37.h 22:24 <@AceLan> 22:24 <@AceLan> 這時目錄結構長的像這樣 22:24 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/h4x37$ ls 22:24 <@AceLan> form1.ui form1.ui.h h4x37 h4x37.pro include main.cpp Makefile src 22:24 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/h4x37$ ls src 22:24 <@AceLan> h4x37.cpp 22:24 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/h4x37$ ls include/ 22:24 <@AceLan> h4x37.h 22:24 <@AceLan> 22:25 <@AceLan> h4x37.h 裡面放 class H4x37 的宣告,程式碼長的像這樣 22:25 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/h4x37$ cat include/h4x37.h 22:25 <@AceLan> #include 22:25 <@AceLan> #include 22:25 <@AceLan> #include 22:25 <@AceLan> class H4x37 : public QTextEdit 22:25 <@AceLan> { 22:25 <@AceLan> public: 22:25 <@AceLan> H4x37( const QString&); 22:25 <@AceLan> QString getText(); 22:25 <@AceLan> private: 22:25 <@AceLan> QString text; // 儲存英文字串 22:25 <@AceLan> QMap dict;// 轉換表 22:25 <@AceLan> }; 22:25 <@AceLan> 22:25 <@AceLan> h4x37.cpp 裡面放 class H4x37 的定義 22:25 <@AceLan> acelan@acelan-nb:~/people/acelan/tech/irc_conference/h4x37$ cat src/h4x37.cpp 22:25 <@AceLan> #include 22:25 <@AceLan> #include 22:25 <@AceLan> #include 22:25 <@AceLan> #include "include/h4x37.h" 22:26 <@AceLan> H4x37::H4x37( const QString& text) 22:26 <@AceLan> { 22:26 <@AceLan> this->text= text; 22:26 <@AceLan> QFile file("h4x37.dic" ); 22:26 <@AceLan> if ( file.open( IO_ReadOnly ) ) 22:26 <@AceLan> { 22:26 <@AceLan> QTextStream stream( &file ); 22:26 <@AceLan> QString line; 22:26 <@AceLan> while ( !stream.atEnd() ) 22:26 <@AceLan> { 22:26 <@AceLan> line= stream.readLine();// line of text excluding '\n' 22:26 <@AceLan> QValueVector words; 22:26 <@AceLan> QStringList wordlist= QStringList::split(" ", line); 22:26 <@AceLan> QString id= *(wordlist.begin());// 第一個是 id 22:26 <@AceLan> dict.insert( QMap< QString, QStringList>::value_type( id, wordlist)); 22:26 <@AceLan> } 22:26 <@AceLan> file.close(); 22:26 <@AceLan> } 22:26 <@AceLan> } 22:26 <@AceLan> QString H4x37::getText() 22:26 <@AceLan> { 22:26 <@AceLan> QString str; 22:26 <@AceLan> for( unsigned int i= 0; i< text.length(); i++) 22:27 <@AceLan> { 22:27 <@AceLan> if( dict.count( QString( text[ i]))) 22:27 <@AceLan> { 22:27 <@AceLan> QStringList temp( dict[ QString( text[ i])]); 22:27 <@AceLan> QStringList::iterator iter= temp.begin(); 22:27 <@AceLan> iter+= rand()% temp.size(); 22:27 <@AceLan> str.append( *iter); 22:27 <@AceLan> } 22:27 <@AceLan> else 22:27 <@AceLan> str.append( text[ i]); 22:27 <@AceLan> } 22:27 <@AceLan> return str; 22:27 <@AceLan> } 22:27 <@AceLan> 22:27 <@AceLan> 程式碼有點長,有興趣的可以慢慢看 :p 22:27 <@AceLan> 22:27 <@AceLan> 我們的程式寫好之後,到 Object Explorer 的 Members tab 那,在 Includes (in Declaration) 那加入我們的 .h 檔 "include/h4x37.h" 22:27 <@AceLan> 22:27 <@AceLan> 然後選 toolbar 上的 Project->Add File... 加入 src/h4x37.cpp,這樣就大功告成啦。 22:27 <@AceLan> 22:29 <@AceLan> 原本的 void Form1::textEdit1_returnPressed() 要改成這樣 22:29 <@AceLan> void Form1::textEdit1_returnPressed() 22:29 <@AceLan> { 22:29 <@AceLan> H4x37 h4x37( textEdit1->text()); 22:29 <@AceLan> textEdit2->setText( h4x37.getText()); 22:29 <@AceLan> } 22:29 <@AceLan> 22:29 <@AceLan> 全部存檔之後從 qmake 開始作,make 完之後應該就會有個可以玩的 hacker language translator 了(http://kde.linux.org.tw/~acelan/irc_conference/qt16.png)。 22:29 <@jesse_> http://gallery.debian.org.tw/20031018/qt16 22:30 <@AceLan> 22:30 <@AceLan> 到這邊有什麼問題嗎 22:30 <@AceLan> 程式碼的部份用到了很多 Qt 的東西 22:31 <@AceLan> 這邊要靠原本 C++ 個功力 22:31 <@AceLan> 所以我就跳過沒有講解 22:32 <@AceLan> 程式碼可以到這邊抓 http://kde.linux.org.tw/~acelan/irc_conference/h4x37/ 22:33 <@AceLan> 我們還有一個簡單的 image browser 要寫,打起精神來,不要打瞌睡喔,你們在台下作什麼,老師都看的一清二楚的 :p 22:33 < saviro> .... 22:33 <@jesse_> ccc 22:33 <@AceLan> ccCc 22:33 < jrgl> 精神百倍...:p 22:34 <@AceLan> 這個程式是比較難 demo 啦 如果沒有程式基礎的話 可能會看不懂 22:34 <@AceLan> 不過下一個就簡單很多了 22:34 <@AceLan> 我們就一口氣把他講完吧 :p 22:35 <@AceLan> 22:35 <@AceLan> 其實 image browser 真的是非常簡單,只是要展示一下要如何選取檔案而已,那我們現在要開始囉。 22:35 <@AceLan> 22:35 <@AceLan> 首先先拉出這樣的畫面(http://kde.linux.org.tw/~acelan/irc_conference/qt17.png) 22:35 <@jesse_> http://gallery.debian.org.tw/20031018/qt17 22:35 <@AceLan> 22:35 <@AceLan> 上面是 pixmapLabel,下面是 lineEdit & pushButton。 22:35 <@AceLan> 22:36 <@AceLan> 首先我們先來處理 pushButton clicked 的動作。 22:36 <@AceLan> void Form1::pushButton1_clicked() 22:36 <@AceLan> { 22:36 <@AceLan> QString file = QFileDialog::getOpenFileName( 22:36 <@AceLan> ".", // 號徑 22:36 <@AceLan> "Images (*.png *.xpm *.jpg)", // filter 22:36 <@AceLan> this, // Parent 22:36 <@AceLan> "open file dialog" // Name caption 22:36 <@AceLan> "Choose a file" ); 22:36 <@AceLan> lineEdit1->setText( file); 22:36 <@AceLan> } 22:36 <@AceLan> 22:36 <@AceLan> 因為我們用到了 QFileDialog,所以在 Object Explorer 的 Members tab 裡的 includes(in Implementation) 那要加上 。 22:36 <@AceLan> 22:37 <@AceLan> 然後在 new 一個 main() 之後試著去編譯看看,看看會不會跑出一個檔案選取的對話盒。 22:37 <@AceLan> 22:37 <@AceLan> 選完之後 lineEdit 有沒有出現剛剛所選取的檔案路徑跟檔名。 22:37 <@AceLan> 22:37 <@AceLan> 接著,我們要顯示出這張圖片非常的簡單,只要填入 pixmapLabel 的一個欄位值就可以了 22:37 <@AceLan> 22:38 <@AceLan> 在 lineEdit1->setText( file); 的下面多這一行 pixmapLabel1->setPixmap( QPixmap( file)); 22:38 <@AceLan> 22:38 <@AceLan> 怎麼樣,夠簡單了吧,這樣就可以瀏覽圖片了(http://kde.linux.org.tw/~acelan/irc_conference/qt18.png) 22:38 <@AceLan> 22:38 <@jesse_> http://gallery.debian.org.tw/20031018/qt18 22:38 <@AceLan> 小弟的 Qt 程式設計無痛起步就介紹到這邊,謝謝各位的蒞臨指教 m(_ _)m 22:38 <@AceLan> ^_^ 22:39 <@jesse_> 感謝 AceLan ! 22:39 <@AceLan> 終於講完了 ^_^ 22:39 <@jesse_> 有朋友要提問題嗎? 22:39 < jrgl> AceLan: 感謝感謝!^^ 22:39 /*/ [In] drake___ (~drake@61-219-155-230.HINET-IP.hinet.net) has joined #debian.tw 22:39 < anychris> 跟 java 蠻像的.. 22:39 < jrgl> AceLan: 會不會專門開一堂課講signal/slot? 22:39 <@jesse_> 補充一下... log 稍晚我會整理到 http://ircconf.debian.org.tw/ 22:39 <@AceLan> jrgl: 不會 :p 22:40 <@jesse_> 圖片在 http://gallery.debian.org.tw/20031018 都可以找到 22:40 <@AceLan> jesse_: 那我的程式要放在 dot 上嗎 22:40 <@jesse_> jrgl: 下次再請 AceLan 來講 signal/slot.. :) 22:40 * AceLan 撲通地跌了一跤。 22:41 < jrgl> jesse_: 好阿...鼓掌..鼓掌.. 22:41 < winfred> 鼓掌! 22:41 <@AceLan> 不好啦 你看大家都睡著了 22:41 * jesse_ 鼓掌鼓掌.. 啪啪啪啪 22:41 <@AceLan> @_@ 22:41 * winfred 啪啪啪啪啪啪啪啪啪啪啪啪 22:41 < jrgl> 安可....安可...:-) 22:41 <@AceLan> ... 22:41 <@jesse_> 還有朋友要提問題嗎? 22:42 < drake___> 慢上來的人,等著看 log :p 22:42 < winfred> 能不能偵對qt和gtk稍作比較其優劣? :> 22:42 <@AceLan> 我今天的講稿還有圖片 & 程式可以到這裡抓 http://kde.linux.org.tw/~acelan/irc_conference.tgz 22:43 <@kevinwatt> 感謝 AceLan ! 22:43 <@AceLan> winfred: 幸好刀疤蔡不在 不然你要我說這種話題會被砍死 :p 22:43 < jrgl> 感謝Acelan 22:43 < descent> 啪啪啪啪啪啪啪啪啪啪啪啪 22:43 < descent> 辛苦了哦 22:43 < jrgl> 趁刀疤菜不在,就說一說吧 22:43 <@jesse_> 我會放在 dot 上, 網址再公佈在 ircconf.deabin.org.tw 上 22:43 <@AceLan> 講稿我剛剛在講的時候發現裡面漏了一小段 22:43 < saviro> 怎麼查qt 已經有的 函式 和 物件 會比較快呢? 22:44 <@AceLan> 所以 irc 上的 log 會比較完整一點 22:44 <@AceLan> saviro: qt3-doc 22:44 /*/ [Out] descent (a@u248-157.u61-71.giga.net.tw) has quit [Leaving] 22:44 /*/ [In] descent (a@u248-157.u61-71.giga.net.tw) has joined #debian.tw 22:44 <@AceLan> saviro: 裡面有完整的 Qt 說明網頁 22:44 < descent> 下次是什麼時候 22:45 < R7chars> http://www.trolltech.com/products/qt/classchart.html?cid=4 ? :P 22:45 <@AceLan> saviro: 內容跟這裡一樣 http://doc.trolltech.com/3.2/index.html 22:45 <@jesse_> descent: 會再公告 :) 22:45 <@csardas> 趴趴啪拍 22:45 <@AceLan> candyz: 哼哼 你根本就睡著了 22:45 <@AceLan> 亨錯人 :p 22:46 <@jesse_> XD 22:46 < winfred> XD 22:46 <@AceLan> csardas: 哼哼 你根本就睡著了 22:46 <@csardas> 其實是看到刀鋒站士...XD 22:46 <@jesse_> 今天的 ircconf 到這裡囉! 感謝 AceLan , 也感謝各位的參與! :) 22:46 <@csardas> 就被電視黏走了..XD 22:46 <@AceLan> 感謝各位 ^_^ 22:46 <@csardas> AceLan++ 22:46 * jesse_ 啪啪啪啪啪 22:46 < anychris> 謝謝 22:47 < jrgl> AceLan++++++++ 22:47 <@jesse_> AceLan: 大家都這麼期待, 安可一下吧... 再來一場.. ^^ 22:47 * AceLan 貪婪地舔了舔 jrgl 的臉。 22:47 * AceLan 撲通地跌了一跤。 22:47 < jrgl> 安可....安可....安可....安可....安可....安可.... 22:48 <@csardas> 安可安可