`
nightkidzxc
  • 浏览: 10966 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

QT学习笔记

 
阅读更多
QT是构造图形用户界面所使用的工具包


Project 1:Hello QT
#include <QApplication>
#include <QLabel>
int main(int argc,char *argv[])
{
QApplication app(argc,argv);//创建QApplication对象,管理应用程序资源
QLabel *label=new QLabel("Hello Qt");//QLabel是小控件,显示一行文本
label->show();//显示QLabel
return app.exec();//让程序进入消息循环,等待可能的菜单工具,鼠标等的输入
}
其中QLabel *label=new QLabel("<h2><i>hello</i> <font color=red>Qt!</font></h2>");
小细节:新控件声明前面要加*,代表指针的意思






Project 2:SIGNAL
#include <QApplication>
#include <QLabel>
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QPushButton *button=new QPushButton("EXIT");//注意一定要有后面的new QPushButton
QObject::connect(button,SIGNAL(clicked),&app,SLOT(quit()));//QObject::connect(发送者,什么信号,接受者,怎么办)
button->show();//面向对象中 指针对象就要用->来引用成员
return app.exec();


}
小细节:QObject::connect()里接受者对象前面加采用引用&app






Project 3:控件使用
#include <QApplication>
#include <QSlider> 滑动条
#include <QSpinBox> 旋转盒
#include <QHBoxLayout> 水平排列
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QWidget *par=new QWidget;//声明一个QWidget作窗口
par->setWindowTitle("Enter Your Age");//设置窗口的标题
QSlider *slider=new QSlider;//声明一个滑动条
QSpinBox *spinBox=new QSpinBox;//声明一个旋转盒
slider->setRange(0,100);//设置滑动条的范围
spinBox->setRange(0,100);//设置旋转盒的取值范围
QObject::connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));//滑动条值变化引起旋转盒值的变化
QObject::connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));//旋转盒值的变化引起滑动条值的变化 这里的两个就不用加& 因为没有本质改变这两个控件
spinBox->setValue(35);//初始一个spinBox的值
//布置一下控件格局layout
QHBoxLayout *layout=new QHBoxLayout;//声明一个布局

layout->addWidget(spinBox);//把两个控件加到格局中
layout->addWidget(slider);

//格局有了,把窗口的格局设置成这个
par->setLayout(layout);
par->show();
return app.exec();
}
//细节总结:QWidget类->setWindowTitle("blabla");QWidget类->setLayout(某layout类成员);
声明。触发事件的连接QObject::connect(); 声明横向的QSlider slider=new slider(Qt::Horizontal)
新遇到的类:QHBoxLayout横向排列; QVBoxLayout垂直排列;QGridLayout按矩阵方式排列
虽然我们还没有看见spinBox 和slider 控件的大小和位置,它们已经水平排列好了。
QHBoxLayout 能合理安排它们。我们不用在程序中考虑控件在屏幕上的大小和位置这些头
疼的事情了,交给布局管理器就万事大吉。
在Qt 中建立用户界面就是这样简单灵活。程序员的任务就是实例化所需要的控件,按
照需要设置它们的属性,把它们放到布局管理器中。界面中要完成任务由Qt 的signal 和
slot 完成。






project4:dialogs 创建一个查找(Ctrl+F)对话框
其中.h文件,即配置文件如下:


#ifndef finddialog_H
#define finddialog_H
#include <QDialog>
class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton;//类的向前声明,编译器就知道这个类已经存在,而不用写出包含的头文件
//实际上这个文件就是在声明一个自定义的类和声明控件
class finddialog : public QDialog //自定义的类finddialog,继承自QDialog
{
Q_OBJECT //是一个宏定义,如果类中用到了signal或者slots就要声明
public:
finddialog(QWidget *parent = 0);//构造函数,此处没有父控件
signals://说明这个对话框发出的两个信号
void findNext(const QString &str,Qt::CaseSensitivity cs);//CaseSensitivity大小写敏感
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
在类的私有部分,声明有两个slot 函数。为了实现这两个函数,需要用到对话框的其
他控件的信息,所以保存了一些控件的指针。slot 关键字和signal 一样,也是一个宏。
对于私有成员变量,我们只是使用了它们的指针,没有对它们进行存取操作,编译器
不需要知道它们的详细定义,所以只使用了这些类的前向声明




.cpp文件,即定义文件,内容如下
#include "finddialog.h"
#include <QtGui>
finddialog::finddialog(QWidget *parent):QDialog(parent)//在类的外部定义类的构造函数,继承自QDialog的构造函数
{
label=new QLabel(tr("Find&what?"));//声明一个label,搜索框前面的文字label,一个&符号后面的一个字母下划线,★!!代表按下ALT+W就选中这个!!★
lineEdit=new QLineEdit;//LineEdit就是一行输入框
label->setBuddy(lineEdit);//★!!代表选中上面那个焦点集中在lineedit!!★
caseCheckBox=new QCheckBox(tr("Match&case"));//一个复选框,后面的选项内容为Matchcase,既是否区分大小写
backwardCheckBox=new QCheckBox(tr("Search&backward"));//一个复选框,后面的选项内容为Searchbackward
findButton=new QPushButton(tr("&Find"));//一个按钮
findButton->setDefault(true);//设置默认,用户直接按回车就按这个button
findButton->setEnabled(false);//设置findButton开始不能用(因为此时没有填入搜索值)
closeButton=new QPushButton(tr("Close"));//关闭按钮
connect(lineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(enableFindButton(const QString &)));
//一旦编辑框lineEdit里面的值发生了变化,就会触发在.h文件中声明过,下面定义的enableFindButton方法设置button可用,猜测this为这个面板
connect(findButton,SIGNAL(clicked()),this,SLOT(findClicked()));
//一旦findButton被点到,触发.h文件中声明过的,下面定义的findClicked方法
connect(closeButton,SIGNAL(clicked),this,SLOT(close()));
//一旦closeButton被点击,关闭窗口
QHBoxLayout *topLeftLayout=new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit);//先是一个横向(QHBoxLayout)布局,包括Findwhat的label和输入框
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);
this->setLayout(mainLayout);
setWindowTitle(tr("Find"));//此处省略了this,原应该为QApplication对象,这么包括上面connect的接受者都用了this,因为现在在编辑这个继承来的类
setFixedHeight(sizeHint().height());//设置一个默认的高度
}


void finddialog::findClicked() //因为这两个方法都是private的,所以用::
{
{
QString text = lineEdit->text();//把要搜索的值取出给text
Qt::CaseSensitivity cs = //cs就是CaseSensitivity,大小写是否敏感
caseCheckBox->isChecked() ? Qt::CaseSensitive: Qt::CaseInsensitive; //如果Matchcase勾选上了,选择区分大小,不勾不区分
if (backwardCheckBox->isChecked()) //如果backward被勾选住了,选择触发findPrevious方法向前查找,不勾findNext
{
emit findPrevious(text, cs);//因为后面的find是信号,所以要用emit发射
}
else
{
emit findNext(text, cs);
}
}
}
void finddialog::enableFindButton(const QString &text)
{
findButton->setEnabled(!text.isEmpty());
}


main函数文件,很简单,声明显示即可:
#include "finddialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
finddialog *dialog = new finddialog;
dialog->show();
return app.exec();
}






project5:信号与槽 用QT Designer快速实现对话框
槽和普通的c++成员函数很像,不同在于一个槽函数能和一个信号相连接,只要信号发出了,这个槽函数就会自动被调用。
一个信号可以和另一个信号相连
connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SIGNAL(updateRecord(const QString &)));
信号和槽函数必须有着相同的参数类型,这样信号和槽函数才能成功连接,如果信号里的参数个数多于槽函数的参数,多余的参数被忽略。


★★★namespace Ui {//namespace是为了解决命名冲突的问题,这样使用Ui_GoToCellDialog的时候就可以用Ui::GoToCellDialog来代替。
class GoToCellDialog: public Ui_GoToCellDialog {};


} // namespace Ui


★★★class GoToCellDialog : public QDialog, public Ui::GoToCellDialog//多继承 继承于两个类
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
   {
    <派生类类体>
   };
此处这句代码 GoToCellDialog继承自类Qdialog和前面已经用namespace改过名的Ui::GoToCellDialog两个类


继承类的符号是一个冒号: -.=


槽就是函数,信号就是事件
对话框布局小总结:
1.首先#include需要的头文件
2.然后定义一个自定义的对话框类:其中又包括先声明各种控件
再定义一个方法,参数是一个QWidget对象,实现把一个对象变成一个对话框样式
包括对控件的声明,对布局的声明,布局的添加等
3.声明一个这个类的对象,使用上一步写好的函数把它加工成对话框,show出来


官方说法是:
创建对话框有如下基本的步骤:
1、创建和初始化子控件。
2、把子控件放到布局管理器中。
3、设置tab 顺序。
4、创建信号和槽。
5、实现对话框的自己的槽函数。


理论到此,实践开始:
gotocelldialog.h文件:
#ifndef GOTOCELLDIALOG_H
#define GOTOCELLDIALOG_H
#include <QDialog>
#include "ui_gotocelldialog.h"
class GoToCellDialog:public QDialog,public Ui::GoToCellDialog//继承自两个类
{
Q_OBJECT
public:
GoToCellDialog(QWidget *parent=0);//在cpp文件中会有定义
private slots:
void on_lineEdit_textChanged();//在cpp文件中会有定义
};
#endif


gotocelldialog.cpp文件:
#include <QtGui>
#include "gotocelldialog.h"
//在类外定义类的构造函数
GoToCellDialog::GoToCellDialog(QWidget *parent)
:QDialog(parent)//继承自QDialog的构造函数,在构造函数中进行了界面匹配,验证,连接
{
setupUi(this);//★★★这个是用designer配置好后自己匹配的,或者在ui_gotocelldialog中自己定义的setupUI
QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
lineEdit->setValidator(new QRegExpValidator(regExp,this));
//设置编辑框的验证
connect(okButton,SIGNAL(clicked()),this,SLOT(accept()));//
connect(cancelButton,SIGNAL(clicked()),this,SLOT(reject()));
//还不知道accept() reject()是怎么定义的
}
//定义类中的SLOT
void GoToCellDialog::on_lineEdit_textChanged()
{
okButton->setEnabled(lineEdit->hasAcceptableInput());
}


main.cpp文件:
#include <QApplication>
#include "gotocelldialog.h"
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
GoToCellDialog *dialog=new GoToCellDialog;
dialog->show();
return app.exec();
}


























project 6:可变的对话框----用QT Designer设计
★!!!其中的more按钮要改变其属性为checkable,否则toggle没有用的!!!★
首先,设计好ui文件的布局
然后,储存编译后系统会自动生成ui_trySortDialog.h文件 其中包括基本的外形类,只需要在后面进行 继承即可
外形类的名称为Ui_文件名 此处为class Ui_trySortDialog
ui_trySortDialog.h文件大概是这样


#ifndef UI_TRYSORTDIALOG_H
#define UI_TRYSORTDIALOG_H
#include <QtCore/QVariant>
...
#include <QtGui/QVBoxLayout>
class Ui_trySortDialog
{
public:
引用控件...
void setupUi(QDialog *trySortDialog)
{
布局
}
void retranslateUi(QDialog *trySortDialog)
{
配置属性
}
}; //这里有一个分号 下面有新的命名空间


namespace Ui{
class trySortDialog:public Ui_trySortDialog{};
}
//前面也说过,这里只是改一下名字,之前写的类Ui_trySortDialog以后用的时候用Ui::trySortDialog代替
#endif




然后是trySortDialog.h文件,只是对类进行继承和新方法的声明:


#ifndef TRYSORTDIALOG_H
#define TRYSORTDIALOG_H
#include <QDialog>
#include "ui_trysortdialog.h"//引用了之前自动生成的类,可以进行继承
class trySortDialog : public QDialog,public Ui::trySortDialog
//这里对之前改过名字的Ui::trySortDialog和QDialog进行多继承,子类名为trySortDialog,这里可以额外定义方法
{
Q_OBJECT
public:
trySortDialog(QWidget *parent = 0);//声明了构造函数,cpp中详细定义
void setColumnRange(QChar first, QChar last);//子类定义的方法,cpp中详细定义
};
#endif // TRYSORTDIALOG_H


然后是trySortDialog.cpp文件


#include <QtGui>
#include "trysortdialog.h"
trySortDialog::trySortDialog(QWidget *parent)
: QDialog(parent)//先对构造函数进行定义,其中继承了QDialog的构造函数
{
setupUi(this);//setupUI函数进行布局
secondaryGroupBox->hide();//设置新的要求,比如隐藏
tertiaryGroupBox->hide();
★!!!layout会返回一个值到最外面的layout,所以记得把总共这个框生成一个layout!!!★
★!!!否则就会产生越界现象!!!★
layout()->setSizeConstraint(QLayout::SetFixedSize);//设置布局大小
★!!!l注意把其中的spacer的sizeHint 高度设置为0,这样调整时就会隐藏spacer了!!!★
setColumnRange('A', 'Z');//后面定义的函数,功能是添加几个下拉框里的值
}


void trySortDialog::setColumnRange(QChar first, QChar last)
{
primaryColumnCombo->clear();
secondaryColumnCombo->clear();
tertiaryColumnCombo->clear();

secondaryColumnCombo->addItem(tr("None"));
tertiaryColumnCombo->addItem(tr("None"));

primaryColumnCombo->setMinimumSize(secondaryColumnCombo->sizeHint());

QChar ch = first;
while (ch <= last) {
primaryColumnCombo->addItem(QString(ch));
secondaryColumnCombo->addItem(QString(ch));
tertiaryColumnCombo->addItem(QString(ch));
ch = ch.unicode() + 1;
}
}




最后是main函数,功能就是实例化一个类的对象,表现出来


#include <QApplication>
#include "sortdialog.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
trySortDialog *dialog = new trySortDialog;
dialog->setColumnRange('C', 'F');
dialog->show();
return app.exec();
}




那么,总结一下,QT文件的功能分配是这样,
首先由xxx.ui文件进行可视化布局,生成了ui_xxx.h文件
而ui_xxx.h文件中包含了比较初级的类定义
然后有xxx.h文件声明新的类来继承初级定义
xxx.cpp中详细新类的构造函数
main.cpp中来实例化这个对象并显示






QT编写一个简易的EXCEL
首先,main函数里执行的是一个MainWindow类的显示
然后,看mainwindow类的定义.h文件和实现.cpp文件
mainwindow类中包含QAction FindDialog Spreadsheet等几个自定义类需要再研究
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics