2008年2月17日 星期日

GTK+ 馬戲團:邪惡的 g_signal_connect 出場

Standard
GTK+ 馬戲團有五花八門的精彩表演,而今天壓軸好戲就是『邪惡的野獸 - g_signal_connect 』。g_signal_connect 可以戰勝所有的 widget 和 window,有強而有力的爪子,能劃破層層阻礙;有尖銳嚇人的牙齒,只須咬一口便深可見骨。雖然它已被馴服,但隨時還是有機會獸性大發反撲過來。:P

GTK+ Program 本身並不難,就算是第一次接觸的人,也能輕易上手並寫出什麼東西來。但對於較常接觸 GTK+ programing 的人,卻常會抱怨 GTK+ 的設計,層層的 window 和 widget 常搞到什麼事都要兜個大圈才能解決。而對 GTK+ 設計架構和細節了解不夠透徹的人,更是常常寫 5 分鐘 code ,卻要花 5 個小時 debug ,小弟我就是最好的例子 :(

所以,探討 GTK+ 的一些細節,有助於我們在撰寫 GTK+ 程式時避免問題的發生,減少 debug 的時間。

接觸過的人都曉得, GTK+ 的優點就是將各種東西都寫成一個個直接的 function call,任何人都可以很容易的去呼叫使用。但那些 function call 的背後常常各自為政互相打架,卡來卡去的結果不是『無限迴圈』就是『程式流程大亂』,我們如果不深入了解 GTK+ 的運作,這些問題將都會無解。

在 GTK+ 之中很多問題的發生,都是從邪惡的 g_signal_connect 開始。它是 GTK+ 各種物件的共通管道,programer 們可以利用它設定各種狀況的 handler,像是 widget 的 button-press-event, toggled ...etc。不過 g_signal_connect 所決定好的事,卻是有各種不同的觸發時機,有些會馬上就觸發如: toggled 事件,有些會在所有 event 處理完後,idle 時才觸發。若是沒有掌握好觸發的時機,一切的流程設計將會毀滅,而且找不到問題所在。

但是這些不同的時機,要深入了解 GTK+ Source 之後才會發現。對於一般 programer 來說,可沒這麼多時間一一深入了解每一個元件的運作,最好的解決辦法就是養成習慣,所有 widget 和 window 都設定好 Ready 之後,再呼叫 g_signal_connect 設定 event handler,這樣可以避免掉很多問題發生。

當然還有其他 g_signal_connect 衍生的問題,不過不再多提,有機會再整理成文好了。 :P