本文大部分内容学习自《Foundations of Qt Development》

notes

qt name rules

类的名字以大写字母开始,每一个新的词也以大写字母开头,也即骆驼拼写法 (CamelCasing)
方法的名字也遵从CamelCase,但是需要注意的是它以小写字母开头。

protected slots

被protect的slot只有被用作方法的时候才会被保护。私有的或者受保护的slots仍然能够用于connect sigals

meta-object和信号槽机制

meta-object自己知道signals和slots,meta-object compiler (moc) 会用c++实现相关的内容。

signals and slots

qt使用指针实现信号槽,当我们发出信号,实际上也就在调用信号方法,该方法被moc实现。signal方法随即调用slots。源对象和目标对象就是指向QObject或者它的子类的指针。

LIFO and FIFO

LIFO means “last in, first out”. 代表:栈
FIFO means “fist in, first out”. 代表:队列

Qt designer

命令行启动:shell> designer
qt4可能是shell> designer-qt4

widgets

QSlider and progressBar

下面的小应用由dialog, horizontalSlider, progressBar, pushButton, label构成。
第三个progressBar的范围是(0,0),结果时不显示数值结果并不断运动的,第4个progressBar的范围我想设置成无穷大,但不确定这种方法setRange(-1,-1)是否正确。

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
/*
*for QProgressBar format : QString
*This property holds the string used to generate the current text.
*%p - is replaced by the percentage completed. %v - is replaced by the current value. %m - is replaced
*by the total number of steps. The default value is "%p%".
*/
ui->progressBar->setFormat("%p%"); // default
ui->progressBar_2->setFormat("%v out of %m"); //custom text
ui->progressBar_3->setRange(0,0); // hide text and keep moving.
ui->progressBar_4->setRange(-1,-1); // static
connect(ui->horizontalSlider,SIGNAL(valueChanged(int)),ui->progressBar,SLOT(setValue(int)));
connect(ui->horizontalSlider,SIGNAL(valueChanged(int)),ui->progressBar_2,SLOT(setValue(int)));
connect(ui->horizontalSlider,SIGNAL(valueChanged(int)),ui->progressBar_3,SLOT(setValue(int)));
connect(ui->horizontalSlider,SIGNAL(valueChanged(int)),ui->progressBar_4,SLOT(setValue(int)));
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(close()));
}

qt (2) —— 部分部件_ide

QLineEdit

LineEdit的echo mod可以设置成不同的格式,属性MaxLength则设定了能够填写的最大字符数。

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->lineEdit_2->setEchoMode(QLineEdit::Password);
ui->lineEdit_3->setMaxLength(9);
connect(ui->lineEdit,SIGNAL(textChanged(QString)),ui->lineEdit_4,SLOT(setText(QString)));
connect(ui->lineEdit_2,SIGNAL(textChanged(QString)),ui->lineEdit_5,SLOT(setText(QString)));
connect(ui->lineEdit_3,SIGNAL(textChanged(QString)),ui->lineEdit_6,SLOT(setText(QString)));
}

qt (2) —— 部分部件_qt_02

QListWidget

将listWidget放进Dialog后,合理设置layout,我们可以在改变dialog的大小同时产生上下滑动条。
下面的例子对choose and click做了一些处理。
dialog.cpp:

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
for(int i=0;i<10;i++){
ui->listWidget->addItem(QString::number(i)+" item");
}
}

Dialog::~Dialog()
{
delete ui;
}

void Dialog::on_pushButton_clicked()
{
QListWidgetItem *it = ui->listWidget->currentItem();
it->setText("you click "+it->text());
it->setBackground(Qt::black);
it->setTextColor(Qt::red);
}

qt (2) —— 部分部件_应用_03


好好利用QListWidget,如takeItem, addItem等方法,我们可以创建出类似于管理书单的应用窗体。

dialog.h

#ifndef DIALOG_H
#define

#include <QDialog>
#include <QListWidget>
#include <QPushButton>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT
QListWidget *listLeft, *listRight;
QPushButton *buttonLeft, *buttonRight;
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();

private:
Ui::Dialog *ui;
public slots:
void moveRight();
void moveLeft();
};

#endif

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QGridLayout>
#include <QStringList>
#include <QList>
#include <QMessageBox>

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
listLeft = new QListWidget(this);
listRight = new QListWidget(this);
buttonLeft = new QPushButton(">>",this);
buttonRight = new QPushButton("<<",this);
QGridLayout *gLayout = new QGridLayout(this);
gLayout->addWidget(listLeft,0,0);
gLayout->addWidget(listRight,0,1);
gLayout->addWidget(buttonLeft,1,0);
gLayout->addWidget(buttonRight,1,1);
QStringList items;
items<<"apple"<<"pear"<<"banana"<<"peach";
listLeft->addItems(items);

connect(buttonLeft,SIGNAL(clicked()),this,SLOT(moveRight()));
connect(buttonRight,SIGNAL(clicked()),this,SLOT(moveLeft()));
}

Dialog::~Dialog()
{
delete ui;
}
void Dialog::moveLeft(){
if(listRight->selectedItems().count()!=1) return;
QListWidgetItem *item = listRight->takeItem(listRight->currentRow());
listLeft->addItem(item);
}
void Dialog::moveRight(){
if(listLeft->selectedItems().count()!=1) return;
QListWidgetItem *item = listLeft->takeItem(listLeft->currentRow());
listRight->addItem(item);
}

qt (2) —— 部分部件_应用_04

QPushButton

QPushButton可以被设置触发(pressed),接着举一个例子,应用QMessageBox,QPushButton,QString.
工程ButtonDialog,程序运行后,点击toggle me按钮,直到下一次点击它,它一直处于pressed状态。
pro文件:

#-------------------------------------------------
#
# Project created by QtCreator 2017-02-04T18:29:24
#
#-------------------------------------------------

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = ButtonDialog
TEMPLATE = app


SOURCES += main.cpp\
dialog.cpp

HEADERS += dialog.h

FORMS

Dialog.h:

#ifndef DIALOG_H
#define

#include <QDialog>
#include <QPushButton>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
public slots:
void buttonClicked();
void buttonToggled();
private:
Ui::Dialog *ui;
QPushButton *clickButton;
QPushButton *toggleButton;
};

#endif

Dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QVBoxLayout>
#include <QMessageBox>

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
clickButton = new QPushButton("click me",this);
toggleButton = new QPushButton("toggle me",this);
toggleButton->setCheckable(true);
QVBoxLayout *vLayout = new QVBoxLayout(this);
vLayout->addWidget(clickButton);
vLayout->addWidget(toggleButton);
connect(clickButton,SIGNAL(clicked()),this,SLOT(buttonClicked()));
connect(toggleButton,SIGNAL(clicked()),this,SLOT(buttonToggled()));
}

Dialog::~Dialog()
{
delete ui;
}
void Dialog::buttonClicked(){
QMessageBox::information(this,"Clicked","the Button is cliecked.");
}
void Dialog::buttonToggled(){
QMessageBox::information(this,"Toggled",QString("the button is %1!")\
.arg(toggleButton->isChecked()?"pressed":"released"));
}

main.cpp

#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();

return

qt (2) —— 部分部件_ide_05

QLabel

QLabel可是设置shortCut,setBuddy。

在下面的例子中,按下”Alt+1”, 光标会聚焦于LineEdit1,按下”Alt +2”, 光标聚焦于LineEdit2。

qt (2) —— 部分部件_qt_06


dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
ui->label->setText("Line&1");
ui->label_2->setText("Line&2");
ui->label->setBuddy(ui->lineEdit);
ui->label_2->setBuddy(ui->lineEdit_2);
}

Dialog::~Dialog()
{
delete ui;
}

QComboBox

假设在类中声明了slot,我们一定要在cpp中定义。
comboBox.h

#ifndef COMBOBOX_H
#define

#include <QDialog>

namespace Ui {
class ComboBox;
}

class ComboBox : public QDialog
{
Q_OBJECT

public:
explicit ComboBox(QWidget *parent = 0);
~ComboBox();
public slots:
void myshow(); //show is key word, care about it.
private:
Ui::ComboBox *ui;
};

#endif

comboBox.cpp

#include "combobox.h"
#include "ui_combobox.h"
#include <QFontComboBox>
#include <QMessageBox>

ComboBox::ComboBox(QWidget *parent) :
QDialog(parent),
ui(new Ui::ComboBox)
{
ui->setupUi(this);
QFont font("KaiTi_GB2312",16);
ui->comboBox->setFont(font);
int i;
for(i=0;i<10;i++){
ui->comboBox->addItem(QString::number(i)+" item");
}

connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(myshow()));
}
void ComboBox::myshow(){
QMessageBox::information(this,"choosed",ui->comboBox->currentText());
}

ComboBox::~ComboBox()
{
delete ui;
}

main.cpp

#include "combobox.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ComboBox w;
w.show();

return

qt (2) —— 部分部件_ide_07

QSPinBox + LCD Number

在designer中进行connect设置,连接spinBox的valueChanged()和LCD number的display()。QDoubleSpinBox相比QSpinBox提供了更高的精度。

qt (2) —— 部分部件_ide_08


qt (2) —— 部分部件_ide_09

QCalender + QDateTime

QCalender和QDateTime(QDate)均可表示日期。前者更加直观,后者更加精确,容易修改。

qt (2) —— 部分部件_应用_10

)

qt (2) —— 部分部件_#include_11

QGridLayout

GridLayout很强大,因为它灵活,坐标定位,所以用起来很方便。

#include <QApplication>
#include <QGridLayout>
#include <QLabel>
#include <QDialog>
#include <QString>

int main(int argc,char *argv[]){
QApplication app(argc,argv);
QDialog dlg;
dlg.resize(400,400);
dlg.show();
QGridLayout *grid = new QGridLayout(&dlg);
int i,j;
int counter = 1;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
QLabel *label = new QLabel(QString::number(counter));
label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
grid->addWidget(label,i,j);
counter++;
}
}
grid->setMargin(2);
return

qt (2) —— 部分部件_qt_12

QVBoxLayout

.pro

SOURCES += \
main.cpp
QT

main.cpp

#include <QApplication>
#include <QLabel>
#include <QDialog>
#include <QVBoxLayout>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QGridLayout>
#include <QDebug>

int main(int argc,char *argv[]){
QApplication app(argc,argv);
QDialog dlg;
dlg.resize(100,200);
dlg.show();
QLabel *label = new QLabel("hello world.");
label->show();
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok
|QDialogButtonBox::Cancel);
QVBoxLayout *vLayout = new QVBoxLayout(&dlg);
vLayout->addWidget(label);
vLayout->addStretch();
vLayout->addWidget(buttons);
return

qt (2) —— 部分部件_ide_13