C++ GUI Programming with Qt4 笔记

  以 finddialog 为例,介绍 QDialog。并对 Qt 的基本概念和技巧做了更进一步(chap1)的介绍。
  
  1.MOC 扩展与signals–slots 机制
  
  严格来说,Qt 开发,写的并不是标准 C++。
  
  Meta-Object System 是 Qt 对 C++ 的一项重要扩展,简称 moc。
  
  moc is a mechanism for creating independent software components
  
  that can be bound together without any component knowing anything about the other components it is connected to
  
  提供了 2 个关键内容:signals–slots and introspection。
  
  其中,introspection 是实现 signals–slots 的基础。
  
  The mechanism works as follows:
  
  The Q_OBJECT macro declares some introspection functions that must be implemented in every QObject subclass: metaObject(), tr(), qt_metacall(), and a few more.
  
  Qt‘s moc tool generates implementations for the functions declared by Q_OBJECT and for all the signals.
  
  QObject member functions such as connect() and disconnect() use the introspection functions to do their work.
  
  All of this is handled automatically by qmake, moc, and QObject, so you rarely need to think about it.
  
  But if you are curious, you can read the QMetaObject class documentation
  
  and have a look at the C++ source files generated by moc to see how the implementation works.
  
  2. 技巧与细节
  
  2.1 class forward declaration
  
  在头文件中,如果只用到了某个类的指针,不依赖于类的定义与实现。
  
  可以使用 class ClassName 声明类,取代 #include "ClassName.h"
  
  相比于加载头文件,前置声明更简洁,性能更好。
  
  2.2 国际化:用户可见的文字,使用 tr()
  
  2.3 快捷键:使用 & 声明快捷键。
  
  例如 &Find 声明快捷键为 F,
  
  setBuddy(widget) 设置快捷键按下时,focus 到 widget 组件上,而非自身。
  
  2.4 setDefault 按下 Enter 键时的行为。
  
  2.5 setLayout 时会重新计算父子关系。
  
  layout 中的所有组件,都变成 setLayout 对象的子对象。
  
  2.6 使用 moc 机制(Q_OBJECT)时,类的定义必须在 .h 文件中,否则 moc 不会正常工作。
  
  bubuko.com,布布扣
  
  // finddialog.h
  
  #ifndef FINDDIALOG_H
  
  #define FINDDIALOG_H
  
  #include <QDialog>
  
  class QCheckBox;
  
  class QLabel;
  
  class QLineEdit;
  
  class QPushButton;
  
  class FindDialog : public QDialog
  
  {
  
  Q_OBJECT
  
  public:
  
  FindDialog(QWidget *parent = 0);
  
  signals:
  
  void findNext(const QString &str, Qt::CaseSensitivity cs);
  
  void findPrevious(const QString &str, Qt::CaseSensitivity cs);
  
  private slots:
  
  void findClicked();
  
  void enableFindButton(const QString &text);
  
  private:
  
  QLabel *label;
  
  QLineEdit *lineEdit;
  
  QCheckBox *caseCheckBox;
  
  QCheckBox *backwardCheckBox;
  
  QPushButton *findButton;
  
  QPushButton *closeButton;
  
  };
  
  #endif
  
  bubuko.com,布布扣
  
  bubuko.com,布布扣
  
  // finddialog.cpp
  
  #include <QtGui>
  
  #include "finddialog.h"
  
  FindDialog::FindDialog(QWidget *parent)
  
  : QDialog(parent)
  
  {
  
  // widgets
  
  label = new QLabel(tr("Find &what: "));
  
  lineEdit = new QLineEdit;
  
  label->setBuddy(lineEdit);
  
  caseCheckBox = new QCheckBox(tr("Match &case"));
  
  backwardCheckBox = new QCheckBox(tr("Search &backward"));
  
  findButton = new QPushButton(tr("&Find"));
  
  findButton->setDefault(true);
  
  findButton->setEnabled(false);
  
  closeButton = new QPushButton(tr("Close"));
  
  // connections
  
  connect(lineEdit, SIGNAL(textChanged(const QString &)),
  
  this, SLOT(enableFindButton(const QString &)));
  
  connect(findButton, SIGNAL(clicked()),
  
  this, SLOT(findClicked()));
  
  connect(closeButton, SIGNAL(clicked()),
  
  this, SLOT(close()));
  
  // layout
  
  QHBoxLayout *topLeftLayout = new QHBoxLayout;
  
  topLeftLayout->addWidget(label);
  
  topLeftLayout->addWidget(lineEdit);
  
  QVBoxLayout *leftLayout = new QVBoxLayout;
  
  leftLayout->addLayout(topLeftLayout);
  
  leftLayout->addWidget(caseCheckBox);
  
  leftLayout->addWidget(backwardCheckBox);
  
  QVBoxLayout *rightLayout = new QVBoxLayout;
  
  rightLayout->addWidget(findButton);
  
  rightLayout->addWidget(closeButton);
  
  rightLayout->addStretch();
  
  QHBoxLayout *mainLayout = new QHBoxLayout;
  
  mainLayout->addLayout(leftLayout);
  
  mainLayout->addLayout(rightLayout);
  
  setLayout(mainLayout);
  
  setWindowTitle(tr("Find"));
  
  setFixedHeight(sizeHint().height());
  
  }
  
  void FindDialog::findClicked()
  
  {
  
  QString text = lineEdit->text();
  
  Qt::CaseSensitivity cs =
  
  caseCheckBox->isChecked() ? Qt::CaseSensitive
  
  : Qt::CaseInsensitive;
  
  if (backwardCheckBox->isChecked()) {
  
  emit findPrevious(text, cs);
  
  } else {
  
  emit findNext(text, cs);
  
  }
  
  }
  
  void FindDialog::enableFindButton(const QString &text)
  
  {
  
  findButton->setEnabled(!text.isEmpty());
  
  }
  
  bubuko.com,布布扣
  
  bubuko.com,布布扣
  
  // main.cpp
  
  #include <QApplication>
  
  #include "finddialog.h"
  
  int main(int argc, char *argv[])
  
  {
  
  QApplication app(argc, argv);
  
  FindDialog *dialog = new FindDialog;
  
  dialog->show();
  
  return app.exec();
  
  }

猜你喜欢

转载自www.cnblogs.com/aquariusunny/p/12729787.html
今日推荐