我用Qt寫程序也兩年多了,主要是用這玩意做課程大作業(yè)、課程設(shè)計之類的玩意。期間遇到過很多奇怪的問題,這里做一下整理。
2017-01-31 更新
2016-12-18 更新
有毒的頭文件
我在項目里定義了一個頭文件 global.h,一開始工程可以正常地編譯運行。但是當多個其他的頭文件開始包含global.h的時候,奇怪的時候開始出現(xiàn)了,編譯運行各種報錯,大概意思就是符號Undifined,特別是global.h文件里的變量怎么也找不到,但是語法高亮又是正常的。折騰一通后,發(fā)現(xiàn)是global.h的預處理頭的問題:
#ifndef GLOBAL_H
#define GLOBAL_H
/** src **/
#endif
發(fā)現(xiàn)GLOBAL_H這個宏很可能在Qt內(nèi)部的頭文件中被定義過了,所以只要把GLOBAL_H換一個名字就行了,可是這是Qt自動幫我生成的啊,好坑爹。
神奇的重構(gòu)功能
一旦項目中文件多了之后,想要給某個變量或方法進行重命名,手動操作出錯概率太高,免不了要用IDE提供的重構(gòu)(Refactor)功能。Qt這玩意的變量重構(gòu)似乎不是基于語法樹分析的,好像只是在文本層面進行批量替換。
我為什么這么猜測呢,因為我遇到過一件坑爹事。有一次工程里有一個變量名比較特殊,大概是像qstring、os、process之類的變量名,具體叫什么我不記得了,我對這個變量名進行重構(gòu)后,Qt似乎重構(gòu)了好久,等重構(gòu)完成后,發(fā)現(xiàn)這個Qt的構(gòu)建套件已經(jīng)報廢了,無論編譯構(gòu)建什么工程,都會報錯,而且錯誤來源都是Qt自己的頭文件。
后來我也是折騰了半天,百思不得其解,懷疑是那次重構(gòu)Qt把自己的內(nèi)部頭文件里的變量名也給重構(gòu)了(內(nèi)部頭文件中存在變量剛好和我要重構(gòu)的這個變量名相同)。后來我重新下載了一個Qt,手動把那個敏感的變量重新命名了一下,問題就解決了。
QAbstractButton的類型轉(zhuǎn)換問題
實例化一個對話框QMessageBox,添加自定義的按鈕。代碼寫法如下:
QMessageBox box;
box.setWindowTitle("標題");
box.setText("文字");
QPushButton *connectButton = box.addButton(tr("確定"), QMessageBox::ActionRole);
QPushButton *abortButton = box.addButton(tr("取消"),QMessageBox::ActionRole);
box.exec();
QAbstractButton* btnClicked = box.clickedButton();
QPushButton* btn = dynamic_cast<QPushButton*>(box.clickedButton());
QPushButton* btn = qobject_cast<QPushButton*>(box.clickedButton());
if (btn == connectButton){
this->close();
} else if (btn == abortButton){
;
}
但是實際上QMessageBox的clickButton()方法返回的是QAbstractButton*類型,因此需要進行類型轉(zhuǎn)換,因為QAbstractButton是QPushButton的基類,因此我用的是dynamic_cast。然而我驚訝地發(fā)現(xiàn)這樣寫會報錯:
然后我又試了一下qobject_cast,也不行,最后直接用(QPushButton*)ptr 強轉(zhuǎn)了。我至今也沒搞懂為什么無法進行轉(zhuǎn)換。
不穩(wěn)定的插件
Qt里面有一個Fake Vim,我就試用了一下。那一次打算在頭文件里輸入一個 #include 語句,結(jié)果忘了自己在用Vim,習慣性地打出了第一個字符 # 。 當時Vim不在編輯模式,按理來說對這個輸入應(yīng)該是沒有響應(yīng)的,結(jié)果Qt就崩潰了,沒有保存的修改也丟失了。
自從那次之后,我就不敢用Qt的Fake Vim了。那還是一年多前的事,現(xiàn)在Qt也更新了好多版本,不知道問題修復了沒有。
動態(tài)補充中
其實應(yīng)該還有不少奇怪的問題,不過已經(jīng)記不太清楚了,下次遇到再補充到Qt里來。
其實從以上的文字看我似乎在吐槽Qt,但其實我個人還是比較喜歡用Qt的。IDE用起來還是比較順手的,至少比VS要順手得多。Qt的信號-槽機制我也很喜歡,很多類之間通信的代碼寫起來方便多了,不用寫一堆麻煩的回調(diào)。