qt的一篇入门文章(貌似大部分代码和讲解都来自C++ GUI Programming with QT4)
Qt学习之路(1):前言
Qt是一个著名的C++库——或许并不能说这只是一个GUI库,因为Qt十分庞大,并不仅仅是GUI。使用Qt,在一定程序上你获得的是一个“一站式”的服务:不再需要研究STL,不再需要C++的<string>,因为Qt有它自己的QString等等。或许这样说很偏激,但Qt确实是一个“伟大的C++库”。
我们所使用的Qt,确切地说也就是它的GUI编程部分。C++的GUI编程同Java不同:GUI并不是C++标准的一部分。所以,如果使用Java,那么你最好的选择就是AWT/Swing,或者也可以使SWT/JFace,但是,C++的GUI编程给了你更多的选择:wxWidget, gtk++以及Qt。这几个库我都有接触,但是接触都不是很多,只能靠一些资料和自己的一点粗浅的认识说一下它们之间的区别(PS: 更详尽的比较在前面的文章中有)。
首先说wxWidget,这是一个标准的C++库,和Qt一样庞大。它的语法看上去和MFC类似,有大量的宏。据说,一个MFC程序员可以很容易的转换到wxWidget上面来。wxWidget有一个很大的优点,就是它的界面都是原生风格的。这是其他的库所不能做到的。wxWidget的运行效率很高,据说在Windows平台上比起微软自家的MFC也不相上下。
gtk++其实是一个C库,不过由于C++和C之间的关系,这点并没有很大的关系。但是,gtk++是一个使用C语言很优雅的实现了面向对象程序设计的范例。不过,这也同样带来了一个问题——它的里面带有大量的类型转换的宏来模拟多态,并且它的函数名“又臭又长(不过这点我倒是觉得无所谓,因为它的函数名虽然很长,但是同样很清晰)”,使用下划线分割单词,看上去和Linux如出一辙。由于它是C语言实现,因此它的运行效率当然不在话下。gtk++并不是模拟的原生界面,而有它自己的风格,所以有时候就会和操作系统的界面显得格格不入。
再来看Qt,和wxWidget一样,它也是一个标准的C++库。但是它的语法很类似于Java的Swing,十分清晰,而且SIGNAL/SLOT机制使得程序看起来很明白——这也是我首先选择Qt的一个很重要的方面,因为我是学Java出身的 :) 。不过,所谓“成也萧何,败也萧何”,这种机制虽然很清楚,但是它所带来的后果是你需要使用Qt的qmake对程序进行预处理,才能够再使用make或者nmake进行编译。并且它的界面也不是原生风格的,尽管Qt使用style机制十分巧妙的模拟了本地界面。另外值得一提的是,Qt不仅仅运行在桌面环境中,Qt已经被Nokia收购,它现在已经会成为Symbian系列的主要界面技术——Qt是能够运行于嵌入式平台的。
以往人们对Qt的授权多有诟病。因为Qt的商业版本价格不菲,开源版本使用的是GPL协议。但是现在Qt的开源协议已经变成LGPL。这意味着,你可以将Qt作为一个库连接到一个闭源软件里面。可以说,现在的Qt协议的争议已经不存在了——因为wxWidgets或者gtk+同样使用的是类似的协议发布的。
在本系列文章中,我们将使用Qt4进行C++ GUI的开发。我是参照着《C++ GUI Programming with Qt4》一书进行学习的。其实,我也只是初学Qt4,在这里将这个学习笔记记下来,希望能够方便更多的朋友学习Qt4。我是一个Java程序员,感觉Qt4的一些命名规范以及约束同Java有异曲同工之妙,因而从Java迁移到Qt4似乎困难不大。不过,这也主要是因为Qt4良好的设计等等。
闲话少说,还是尽快开始下面的学习吧!
Qt学习之路(2):Hello, world!
#include <QLabel>
int main( int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel *label = new QLabel( "Hello, world!");
label->show();
return a.exec();
}
#include <QLabel>
int main( int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel *label = new QLabel( "Hello, world!");
label->show();
return app.exec();
}
//...
return app.exec();
#include <QtGui/QPushButton>
int main( int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton *button = new QPushButton( "Quit");
QObject::connect(button, SIGNAL(clicked()), &a, SLOT(quit()));
button->show();
return a.exec();
}
#include <QtGui/QWidget>
#include <QtGui/QSpinBox>
#include <QtGui/QSlider>
#include <QtGui/QHBoxLayout>
int main( int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *window = new QWidget;
window->setWindowTitle( "Enter your age");
QSpinBox *spinBox = new QSpinBox;
QSlider *slider = new QSlider(Qt::Horizontal);
spinBox->setRange(0, 130);
slider->setRange(0, 130);
QObject::connect(slider, SIGNAL(valueChanged( int)), spinBox, SLOT(setValue( int)));
QObject::connect(spinBox, SIGNAL(valueChanged( int)), slider, SLOT(setValue( int)));
spinBox->setValue(35);
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(spinBox);
layout->addWidget(slider);
window->setLayout(layout);
window->show();
return app.exec();
}
#define FINDDIALOG_H
#include <QtGui/QDialog>
class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;
class FindDialog : public QDialog
{
Q_OBJECT
public:
FindDialog(QWidget *parent = 0);
~FindDialog();
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 // FINDDIALOG_H
#include "finddialog.h"
FindDialog::FindDialog(QWidget *parent)
: QDialog(parent)
{
label = new QLabel(tr( "Find &what:"));
lineEdit = new QLineEdit;
label->setBuddy(lineEdit);
caseCheckBox = new QCheckBox(tr( "Match &case"));
backwardCheckBox = new QCheckBox(tr( "Search &backford"));
findButton = new QPushButton(tr( "&Find"));
findButton->setDefault( true);
findButton->setEnabled( false);
closeButton = new QPushButton(tr( "Close"));
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()));
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());
}
FindDialog::~FindDialog()
{
}
void FindDialog::findClicked()
{
QString text = lineEdit->text();
Qt::CaseSensitivity cs = caseCheckBox->isChecked() ? Qt::CaseInsensitive : Qt::CaseSensitive;
if(backwardCheckBox->isChecked()) {
emit findPrevious(text, cs);
} else {
emit findNext(text, cs);
}
}
void FindDialog::enableFindButton( const QString &text)
{
findButton->setEnabled(!text.isEmpty());
}
#include "finddialog.h"
int main( int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}
connect(slider, SIGNAL(valueChanged( int)),
connect(calculator, SIGNAL(divisionByZero()),
this, SLOT(checkErrorCode( int)));
{
Q_OBJECT
public:
Employee() { mySalary = 0; }
int salary() const { return mySalary; }
public slots:
void setSalary( int newSalary);
signals:
void salaryChanged( int newSalary);
private:
int mySalary;
};
{
if (newSalary != mySalary) {
mySalary = newSalary;
emit salaryChanged(mySalary);
}
}
这种机制工作过程是:
本文出自 “豆子空间” 博客,请务必保留此出处http://devbean.blog.51cto.com/448512/199472
本文出自 51CTO.COM技术博客