Qt學習筆記--編程技巧總結



原文:http://blog.csdn.net/dipperkun/article/details/6266103

以命令行的形式改變窗口的現實風格
./xxx -style cde/motif/plastique

根據標籤快捷鍵定位輸入框
QLabel *label = new QLabel(tr("&New"));
QLineEdit *edit = new QLineEdit();
label->setBubby(edit);


默認按鈕:當用戶按下Enter的時候,能夠按下對應的按鈕
button->setDefault(true);

禁止按鈕:顯示爲灰色,不和用戶交互
button->setEnabled(false);

佈局中佔用其他的剩餘空間
layout->addStretch();

設置窗口的固定高度和寬度
dlg->setFixedHeight(dlg->sizeHint().height());
dlg->setFixedWidth(dlg->sizeHint().width());


信號與槽:

  • 一個信號可以連接多個槽
  • 多個信號可以連接同一個槽
  • 一個信號可以與另一個信號連接
  • 連接可以被移除(disconnect)
  • 信號的參數必須和槽的參數相匹配,參數個數可以多於槽的參數個數,多餘的參數將被忽略


利用Qt設計師生成窗口
生成文件dlg.ui;
繼承Ui::Dlg.

  1. //dlg.h  
  2. #include "ui_dlg.h"  
  3. class Dlg : public QDialog, public Ui::Dlg  
  4. {  
  5.     Q_OBJECT  
  6. public:  
  7.     Dlg(QWidget *parent = 0);  
  8.     ...  
  9. private slots:  
  10.     void on_lineEdit_textChanged();  
  11. };  
  12. //dlg.cpp  
  13. #include "dlg.h"  
  14. Dlg::Dlg(QWidget *parent)  
  15.     : QDialog(parent)  
  16. {  
  17.     setupUi(this); // Notice!  
  18.     QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");  
  19.     lineEdit->setValidator(new      
  20.         QRegExpValidator(regExp, this));  
  21.     ...  
  22. }  
  23. void Dlg::on_lineEdit_textChanged()  
  24. {  
  25.     okBtn->setEnabled(lineEdit->hasAcceptableInput());  
  26. }  
  27. ...  
  28. ...  
 

自動連接信號與槽
setupUi函數會自動將符合on_objectName_signalName()命名慣例的任意槽
與相應的objectName的signalName()信號連接到一起。上例中,建立了下面
的信號-槽關係:
connect(lineEdit, SIGNAL(textChanged(const QString &)),
             this, SLOT(on_lineEdit_textChanged()));


刪除父對象時,它的子對象會被自動刪除

通過佈局管理器來管理擴展對話框的窗口大小
layout()->setSizeConstraint(QLayout::SetFixedSize);

設計一個可擴展對話框的基本思路:

  1. 切換按鈕
  2. 信號-槽連接
  3. 不可以改變尺寸大小的佈局


多頁窗口部件有:QTabWidget, QToolBox

項目視圖窗口部件(帶滾動條):QListView, QTreeView, QTableView

爲應用程序提供圖片的方法:

  • 把圖片保存在文件中,並且在運行時載入它們
  • 把XPM文件包含在源代碼中
  • 使用Qt的資源管理機制


使用資源管理機制的方法:

  1. 將圖片放在images/目錄下;
  2. 在xxx.pro加入:RESOURCES = xxx.qrc
  3. 增加資源文件xxx.qrc, 內容形式如下:

  1. <!DOCTYPE RCC>  
  2. <RCC version="1.0">  
  3. <qresource>  
  4.     <file alias="title.png">images/icon.png</file>  
  5.     ...  
  6.     <file>images/abc.png</file>  
  7. </qresource>  
  8. </RC  

源代碼中引用方式:setWindowIcon(QIcon(":/images/icon.png"));
或者 setWindowIcon(QIcon(":/title.png"));


創建菜單欄、工具欄、狀態欄

  1. void MainWin::createActions()  
  2. {  
  3.     newAct = QAction(tr("&New"), this); // 加速鍵N  
  4.     newAct->setIcon(QIcon("images/new.png")); // 圖標  
  5.     newAct->setShortcut(QKeySequence::New);  // 快捷鍵 Ctrl+N  
  6.     // newAct->setShortcut("Ctrl+N");  // 快捷鍵 Ctrl+N  
  7.     newAct->setStatusTip(tr("Create a new file")); // 狀態提示  
  8.     connect(newAct, SIGNAL(triggered()), this, newFile());  
  9.     ...  
  10.     showGridAct->setCheckable(true); // 帶複選框的菜單  
  11.     showGridAct->setChecked(true);   // 選中  
  12.     ...  
  13. }  
  14. // 菜單欄  
  15. void MainWin::createMenus()  
  16. {  
  17.     fileMenu = menuBar()->addMenu(tr("&File")); // file菜單  
  18.     fileMenu->addAction(newAct); // 添加到菜單中  
  19.     ...  
  20.     //QAction *separatorAct;  
  21.     fileMenu->addSeparator(); // 添加間隔器  
  22.     ...  
  23.     editMenu = menuBar()->addMenu(tr("&Edit")); // edit菜單  
  24.     QMenu *subMenu = editMenu->addMenu(tr("&Select")); // 添加子菜單  
  25.     subMenu->addAction(...);  
  26.     ...  
  27. }  
  28. // 工具欄  
  29. void MainWin::createToolBars()  
  30. {  
  31.     fileToolBar = addToolBar(tr("&File"));  
  32.     fileToolBar->addAction(newAct);  
  33.     ...  
  34.     editToolBar = addToolBar(tr("&Edit"));  
  35.     editToolBar = addAction(...);  
  36.     editToolBar = addSeparator();  
  37.     ...  
  38. }  
  39. // 狀態欄  
  40. void MainWin::createStatusBar()  
  41. {  
  42.     locationLabel = new QLabel(tr(" W999 "));  
  43.     locationLabel->setAlignment(Qt::AlignHCenter);  
  44.     locationLabel->setMinimumSize(locationLabel->sizeHint());  
  45.       
  46.     otherLabel = new QLabel;  
  47.     otherLabel->setIndent(3); // 縮進3個字符  
  48.       
  49.     statusBar()->addWidget(locationLabel);  
  50.     statusBar()->addWidget(otherLabel, 1); // 窗口改變時,伸展它  
  51. }  

模態對話框與非模態對話框
模態對話框典型例子:打開文件對話框,警告對話框
非模態對話框典型例子:查找對話框
模態對話框一般在堆中創建,非模態對話框一般在棧中創建
模態對話框使用exec()顯示,非模態對話框使用show()顯示

  1. void MainWin::find()  
  2. {  
  3.     if (!findDlg) // 不存在,創建它  
  4.     {  
  5.         findDlg = new FindDlg(this);  
  6.     }  
  7.     findDlg->show(); // 顯示,並且是非模態的  
  8.     findDlg->raise(); // 位於最上方  
  9.     findDlg->activateWindow(); // 激活  
  10. }  
  11. void MainWin::goTo()  
  12. {  
  13.     GoToDlg dlg(this);  
  14.     if (dlg.exec()) // 模態的  
  15.     {  
  16.         // 對話框返回true(QDialog::Accepted)  
  17.         ...  
  18.     }  
  19.     // 函數結束時,自動銷燬對話框  
  20. }  


創建一個啓動畫面

  1. int main(...)  
  2. {  
  3.     QApplication app(...);  
  4.     QSplashScreen *splash = new QSplashScreen;  
  5.     splash->setPixmap(QPixmap(":/images/splash.png"));  
  6.     splash->show();  
  7.     app.processEvents(); // 處理點擊啓動畫面的事件  
  8.     splash->showMessage(QObject::tr("XXXX YYYYY ..."),  
  9.                         Qt::AlignRight|Qt::AlignTop, Qt::white);  
  10.     MainWin win;  
  11.     splash->showMessage(...);  
  12.     initNetwork(...);  
  13.     ...  
  14.     win.show();  
  15.     splash->finish(&win);  
  16.     delete splash;  
  17.       
  18.     return app.exec();  
  19. }  


MainWindow的中央窗口部件可以爲:

  • 一個標準的Qt窗口部件
  • 一個自定義的窗口部件
  • 一個帶佈局管理器的普通QWidget
  • 一個切分窗口(QSplitter)
  • 一個多文檔工作空間(QMdiArea)


讀寫平臺無關的二進制文件

  1. bool writeFile(QString &fileName)  
  2. {  
  3.     QFile file(fileName);  
  4.     if (!file.open(QIODevice::WriteOnly))  
  5.     {  
  6.         QMessageBox::warning(this, tr(""), tr("Can not write file %1:/n%2")  
  7.                              .arg(file.fileName()).arg(file.errorString()));  
  8.         return false;  
  9.     }  
  10.     QDataStream out(&file);  
  11.     out.setVersion(QDataStream::Qt_4_6);  
  12.     out << quint32(0X11223344);  
  13.     QApplication::setOverrideCursor(Qt::WaitCursor);  
  14.     out << quint8(x) << qint32(y) << QString(str);  
  15.     out << ...  
  16.     ...  
  17.     QApplication::restoreOverrideCursor();  
  18.     return true;  
  19. }  
  20. bool readFile(QString &fileName)  
  21. {  
  22.     QFile file(fileName);  
  23.     if (!file.open(QIODevice::ReadOnly))  
  24.     {  
  25.         QMessageBox::warning(this, tr(""), tr("Can not read file %1:/n%2")  
  26.                              .arg(file.fileName()).arg(file.errorString()));  
  27.         return false;  
  28.     }  
  29.     QDataStream in(&file);  
  30.     in.setVersion(QDataStream::Qt_4_6);  
  31.       
  32.     quint32 magic;  
  33.     in >> magic;  
  34.     if (magic != 0x11223344)  
  35.     {  
  36.         QMessageBox::warning(this, tr(""), tr("The file is not a xxx file."));  
  37.         return false;  
  38.     }  
  39.     QApplication::setOverrideCursor(Qt::WaitCursor);  
  40.     quint8 x;  
  41.     qint32 y;  
  42.     QString str;  
  43.     while (!in.end())  
  44.     {  
  45.         in >> x >> y >> str;  
  46.         in >> ...  
  47.         ...  
  48.     }  
  49.     QApplication::restoreOverrideCursor();  
  50.     return true;  
  51. }  
 

創建一個自定義窗口部件的過程:

  1. 選擇一個合適的窗口部件
  2. 對它子類化
  3. 實現虛函數,改變它的行爲


構建一個可以集成到Qt設計師中的窗口部件

  1. // iconeditor.h  
  2. #ifndef ICONEDITOR_H  
  3. #define ICONEDITOR_H  
  4. #include <QColor>  
  5. #include <QImage>  
  6. #include <QWidget>  
  7. class IconEditor : public QWidget  
  8. {  
  9.     Q_OBJECT // 必須  
  10.     //設計師的屬性編輯器顯示這些自定義屬性  
  11.     Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage)  
  12.             Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)  
  13.               
  14. public:  
  15.             IconEditor(QWidget *parent = 0);  
  16.     void setIconImage(const QImage ℑ);  
  17.     QImage iconImage() const { return image; }  
  18.     void setZoomFactor(int zoom);  
  19.     int zoomFactor() const { return zoom; }  
  20.     QSize sizeHint() const// 窗口的理性尺寸  
  21.       
  22. protected:  
  23.     void mousePressEvent(QMouseEvent *event);  
  24.     void mouseMoveEvent(QMouseEvent *event);  
  25.     void paintEvent(QPaintEvent *event); // 必須  
  26.       
  27. private:  
  28.     QImage image;  
  29.     int zoom;  
  30. };  
  31. #endif  
  32. IconEditor::IconEditor(QWidget *parent)  
  33.     : QWidget(parent)  
  34. {  
  35.     setAttribute(Qt::WA_StaticContents);  
  36.     // 告訴佈局管理器,理想尺寸是它的最小尺寸,不能對它縮小!  
  37.     setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);  
  38.     zoom = 8; // 一個像素將顯示成一個8x8的正方形  
  39.     image = QImage(16, 16, QImage::Format_ARGB32); // 16x16像素的圖片  
  40.     image.fill(qRgba(0, 0, 0, 0)); // 黑色,完全透明  
  41. }  
  42. void IconEditor::sizeHint() const  
  43. {  
  44.     QSize size = zoom * image.size();  
  45.     if (zoom >=3)  
  46.         size += QSize(1, 1);  
  47.     return size;  
  48. }  
  49. void IconEditor::setIconImage(const QImage &img)  
  50. {  
  51.     if (img != image)  
  52.     {  
  53.         image = img.convertToFormat(QImage::Format_ARGB32);  
  54.         update(); // 重繪窗口  
  55.         updateGeometry(); // 告訴佈局管理器,理想尺寸已經發生改變,佈局需要調整  
  56.     }  
  57. }  
 


自動調用的情況:

  • 窗口第一次顯示
  • 大小改變
  • 被遮擋,然後再次顯示

主動調用的情況:
update();
repaint(); // 不常用

  1. void IconEditor::paintEvent(QPaintEvent *event)  
  2. {  
  3.     QPainter painter(this);  
  4.     painter.setPen(palette().forground().color()); // 調色板  
  5.     painter.drawLine(...);  
  6. }  
  7. void IconEditor::mousePressEvent(QMouseEvent *event)  
  8. {  
  9.     if (event->button() == Qt::LeftButton)  
  10.     {  
  11.         setImagePixel(event->pos(), true);  
  12.         ...  
  13.     }  
  14.     else if (event->button() == Qt::LeftButton)  
  15.     {  
  16.         setImagePixel(event->pos(), false);  
  17.         ...  
  18.     }  
  19. }  


窗口屬性Qt::WA_StaticContents
當重新改變窗口部件的大小時,窗口部件的內容並沒有發生改變,
而且內容仍舊保留從窗口左上角開始的特性。這樣就可以避免重繪
已經顯示的區域。

在設計師中集成自定義窗口部件的2種方法

  • 提升法:拖動一個自定義窗口的父窗口對象,右鍵->提示爲...
  • 插件法:創建一個插件庫


當應用程序的最後一個窗口關閉時,程序退出
在main中使用下面語句:
QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );

鍵盤:
Qt::Key_Plus: 對數字小鍵盤起作用,對於大鍵盤,要同時按下Shift
Qt::Key_Enter: 對數字小鍵盤起作用

當定義一個函數時,如果沒有用到其中的參數p,但又不想在編譯時產生警告:
在函數的開頭,使用宏
Q_UNUSED(p);

在QGraphicsItem的paint函數中,如果不希望線的寬度縮放,則
painter->setPen(color); //不指定pen的寬度,或者指定爲0.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章