Qt学习笔记--编程技巧总结

以命令行的形式改变窗口的现实风格
./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.
//dlg.h

  1. #include "ui_dlg.h"  
  2. class Dlg : public QDialog, public Ui::Dlg  
  3. {  
  4. Q_OBJECT  
  5. public:  
  6. Dlg(QWidget *parent = 0);  
  7. ...  
  8. private slots:  
  9. void on_lineEdit_textChanged();  
  10. };  


//dlg.cpp

  1. #include "dlg.h"  
  2. Dlg::Dlg(QWidget *parent)  
  3. : QDialog(parent)  
  4. {  
  5. setupUi(this);  
  6. QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");  
  7. lineEdit->setValidator(new QRegExpValidator(regExp, this));  
  8. ...  
  9. }  
  10. void Dlg::on_lineEdit_textChanged()  
  11. {  
  12. okBtn->setEnabled(lineEdit->hasAcceptableInput());  
  13. }  
  14. ...  
  15. ...  

自动连接信号与槽
setupUi函数会自动将符合on_objectName_signalName()命名惯例的任意槽
与相应的objectName的signalName()信号连接到一起。上例中,建立了下面
的信号-槽关系:
connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(on_lineEdit_textChanged()));
删除父对象时,它的子对象会被自动删除
通过布局管理器来管理扩展对话框的窗口大小
layout()->setSizeConstraint(QLayout::SetFixedSize);
设计一个可扩展对话框的基本思路:
切换按钮;
信号-槽连接;
不可以改变尺寸大小的布局。
多页窗口部件有: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. </RCC>  

4.源代码中引用方式: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. otherLabel = new QLabel;  
  46. otherLabel->setIndent(3); // 缩进3个字符  
  47. statusBar()->addWidget(locationLabel);  
  48. statusBar()->addWidget(otherLabel, 1); // 窗口改变时,伸展它  
  49. }  

模态对话框与非模态对话框
模态对话框典型例子:打开文件对话框,警告对话框
非模态对话框典型例子:查找对话框
模态对话框一般在堆中创建,非模态对话框一般在栈中创建
模态对话框使用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. }  
  21. 创建一个启动画面  
  22. int main(...)  
  23. {  
  24. QApplication app(...);  
  25. QSplashScreen *splash = new QSplashScreen;  
  26. splash->setPixmap(QPixmap(":/images/splash.png"));  
  27. splash->show();  
  28. app.processEvents(); // 处理点击启动画面的事件  
  29. splash->showMessage(QObject::tr("XXXX YYYYY ..."),  
  30. Qt::AlignRight|Qt::AlignTop, Qt::white);  
  31. MainWin win;  
  32. splash->showMessage(...);  
  33. initNetwork(...);  
  34. ...  
  35. win.show();  
  36. splash->finish(&win);  
  37. delete splash;  
  38. return app.exec();  
  39. }  

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. quint32 magic;  
  32. in >> magic;  
  33. if (magic != 0x11223344)  
  34. {  
  35. QMessageBox::warning(this, tr(""), tr("The file is not a xxx file."));  
  36. return false;  
  37. }  
  38. QApplication::setOverrideCursor(Qt::WaitCursor);  
  39. quint8 x;  
  40. qint32 y;  
  41. QString str;  
  42. while (!in.end())  
  43. {  
  44. in >> x >> y >> str;  
  45. in >> ...  
  46. ...  
  47. }  
  48. QApplication::restoreOverrideCursor();  
  49. return true;  
  50. }  

创建一个自定义窗口部件的过程:
选择一个合适的窗口部件;
对它子类化;
实现虚函数,改变它的行为。
构建一个可以集成到Qt设计师中的窗口部件
// iconeditor.h

  1. #ifndef ICONEDITOR_H  
  2. #define ICONEDITOR_H  
  3. #include <QColor>  
  4. #include <QImage>  
  5. #include <QWidget>  
  6. class IconEditor : public QWidget  
  7. {  
  8. Q_OBJECT // 必须  
  9. //设计师的属性编辑器显示这些自定义属性  
  10. Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage)  
  11. Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)  
  12. public:  
  13. IconEditor(QWidget *parent = 0);  
  14. void setIconImage(const QImage &image);  
  15. QImage iconImage() const { return image; }  
  16. void setZoomFactor(int zoom);  
  17. int zoomFactor() const { return zoom; }  
  18. QSize sizeHint() const// 窗口的理性尺寸  
  19. protected:  
  20. void mousePressEvent(QMouseEvent *event);  
  21. void mouseMoveEvent(QMouseEvent *event);  
  22. void paintEvent(QPaintEvent *event); // 必须  
  23. private:  
  24. QImage image;  
  25. int zoom;  
  26. };  
  27. #endif  
  28. IconEditor::IconEditor(QWidget *parent)  
  29. : QWidget(parent)  
  30. {  
  31. setAttribute(Qt::WA_StaticContents);  
  32. // 告诉布局管理器,理想尺寸是它的最小尺寸,不能对它缩小!  
  33. setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);  
  34. zoom = 8; // 一个像素将显示成一个8x8的正方形  
  35. image = QImage(16, 16, QImage::Format_ARGB32); // 16x16像素的图片  
  36. image.fill(qRgba(0, 0, 0, 0)); // 黑色,完全透明  
  37. }  
  38. void IconEditor::sizeHint() const  
  39. {  
  40. QSize size = zoom * image.size();  
  41. if (zoom >=3)  
  42. size += QSize(1, 1);  
  43. return size;  
  44. }  
  45. void IconEditor::setIconImage(const QImage &img)  
  46. {  
  47. if (img != image)  
  48. {  
  49. image = img.convertToFormat(QImage::Format_ARGB32);  
  50. update(); // 重绘窗口  
  51. updateGeometry(); // 告诉布局管理器,理想尺寸已经发生改变,布局需要调整  
  52. }  
  53. }  

自动调用的情况:
窗口第一次显示;
大小改变;
被遮挡,然后再次显示。
主动调用的情况:

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

窗口属性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.

posted @ 2012-08-28 09:14  latyas  阅读(970)  评论(0编辑  收藏  举报