文章目录
模态和非模态对话框
要使一个对话框成为模态对话框,则只需要调用它的exec()函数;而要使其成为非模态对话框,则可以使用new操作来创建,指定父窗体,然后使用show()函数来显示。
其实使用show()函数也可以建立模态对话框,只须在其前面使用setModal()函数即可。如:
QDialog * dialog = new QDialog(this);
dialog->setModal(true);
dialog->show();
运行程序后可以看到,生成的对话框是模态的。但是,它与用exec()函数时的效果是不一样的。调用show()函数后会立即将控制权交给调用者,程序得以继续往下进行。而调用exec()函数却不同,只有当对话框被关闭时才会返回,控制权才会移交。
与setModal()函数相似的还有一个setWindowModality()函数,它有一个参数来设置模态对话框要阻塞的窗口类型,可以是Qt::NonModal(不阻塞任何窗口,即非模态)、Qt::WindowModal(阻塞它的父窗口、所有祖先窗口以及它们的子窗口)或Qt::ApplicationModal(阻塞整个应用程序的所有窗口)。而setModal()函数默认设置的是Qt::ApplicationModal。
初识信号和槽
简单来说,信号与槽都是函数,比如单击窗口上的一个按钮后想要弹出一个对话框,那么可以将这个按钮的单击信号和自定义的槽关联起来,在这个槽中创建一个对话框并显示它。这个单击这个按钮时就会发射信息,进而执行槽函数来显示一个对话框。
手动关联信号和槽
在编写程序时一般都使用这种connect的方式。
- 添加槽声明
- 添加槽实现
- 使用connect()函数关联信号与槽
自动关联信号和槽
自动关联就是将关联函数整合到槽命名中,由字符on、发射信号的部件对象名和信号名组成。如on_showChildButton_clicked()。用Qt设计器直接生成的槽就是使用这种方式。不过,对于不是在Qt设计器中往界面上添加的部件,就要在调用setupUi()函数前定义该部件,而且还要使用setObjectName()函数指定部件的对象名,这样才可以使用自动关联。
- 添加槽声明
- 添加槽实现
快速Refactor功能
Qt Creator设计了一个快速添加定义的方法:单击添加的槽声明,同时按下Alt + Enter键(也可以在槽声明上右击,在弹出的级联菜单中选择Refactor菜单项),弹出一个弹出菜单,里面有添加实现和更改槽函数名字的选项。
标准对话框
1.颜色对话框
静态函数方式:
void MyWidget::on_colorButton_clicked()
{
QColor color = QColorDialog::getColor(Qt::red, this, tr("颜色对话框"), QColorDialog::ShowAlphaChannel);
qDebug() << "color" << color;
}
创建对象方式:
void MyWidget::on_colorButton_clicked()
{
QColorDialog dialog(Qt::red, this); //创建对象
dialog.setOption(QColorDialog::ShowAlphaChannel); //显示alpha选项
dialog.exec(); //以模态方式运行对话框
QColor color = dialog.currentColor(); //获取当前颜色
qDebug() << "color:" << color; //输出颜色信息
}
2.文件对话框
打开单个文件:
void MyWidget::on_fileButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("文件打开..."), this->windowFilePath(), tr("图片(*.png *.jpg);;所有文件(*.*)"));
qDebug() << "fileName: " << fileName;
}
如果不指定文件过滤器,则默认选择所有类型的文件。这里指定了只选择png和jpg两种格式的图片文件。需要注意,代码中的*.png
和*.jpg
之间需要一个空格。还可以设置多个不同类别的过滤器,不同类别间需要使用两个分号;;
隔开。
打开多个文件getOpenFileNames()、保存文件getSaveFileName()、获取已经存在的文件夹路径getExistingDirectory()的效果和打开单个文件类似。
3.字体对话框
void MyWidget::on_fontButton_clicked()
{
//ok用于标记是否单击了OK按钮
bool ok;
QFont font = QFontDialog::getFont(&ok, this);
//如果单击OK按钮,让“字体对话框”按钮使用新字体
//如果单击Cancel按钮,那么输出信息
if(ok)
{
ui->fontButton->setFont(font);
}
qDebug() << "字体信息:" << font;
}
4.输入对话框
void MyWidget::on_inputButton_clicked()
{
bool ok;
//获取字符串
QString string = QInputDialog::getText(this, tr("输入字符串对话框"), tr("请输入用户名:"), QLineEdit::Normal, tr("admin"), &ok);
if(ok)
{
qDebug() << "string: " << string;
}
int value1 = QInputDialog::getInt(this, tr("输入整数对话框"), tr("输入-1000到1000之间的数值:"), 100, -1000, 1000, 10, &ok);
if(ok)
{
qDebug() << "value1:" << value1;
}
double value2 = QInputDialog::getDouble(this, tr("输入浮点数对话框"), tr("输入-1000到1000之间的数值:"), 0.00, -1000, 1000, 3, &ok);
if(ok)
{
qDebug() << "value2:" << value2;
}
QStringList items;
items << tr("条目1") << tr("条目2");
QString item = QInputDialog::getItem(this, tr("输入条目对话框"), tr("请选择一个条目:"), items, 0, true, &ok);
if(ok)
{
qDebug() << "item:" << item;
}
}
5.消息对话框
void MyWidget::on_msgButton_clicked()
{
int ret1 = QMessageBox::question(this, tr("问题对话框"), tr("你了解Qt吗?"), QMessageBox::Yes, QMessageBox::No|QMessageBox::Default);
if(ret1 == QMessageBox::Yes)
{
qDebug() << tr("问题!");
}
int ret2 = QMessageBox::information(this, tr("提示对话框"), tr("这是Qt书籍!"), QMessageBox::Ok);
if(ret2 == QMessageBox::Ok)
{
qDebug() << tr("提示!");
}
int ret3 = QMessageBox::warning(this, tr("警告对话框"), tr("不能提前结束!"), QMessageBox::Abort);
if(ret3 == QMessageBox::Abort)
{
qDebug() << tr("警告!");
}
int ret4 = QMessageBox::critical(this, tr("严重错误对话框"), tr("发现一个错误!现在要关闭计算机!"), QMessageBox::YesAll);
if(ret4 == QMessageBox::YesAll)
{
qDebug() << tr("错误!");
}
QMessageBox::about(this, tr("关于对话框"), tr("本软件致力于Qt及Qt Creator的普及工作!"));
QMessageBox::aboutQt(this, tr("关于Qt"));
}
6.进度对话框
void MyWidget::on_progressButton_clicked()
{
QProgressDialog dialog(tr("文件复制进度:"), tr("取消"), 0, 5000, this);
dialog.setWindowTitle(tr("进度对话框"));
dialog.setWindowModality(Qt::WindowModal); //设置为模态对话框
dialog.show();
for(int i=0; i<5001; i++) //演示复制进度
{
dialog.setValue(i); //设置进度条的当前值
QCoreApplication::processEvents(); //避免界面冻结
if(dialog.wasCanceled()) //按下取消按钮则中断
{
break;
}
}
QMessageBox::information(this, tr("提示"), tr("复制完成!"), QMessageBox::Ok);
}
7.错误信息对话框
首先打开mywidget.h文件添加类前置声明:
class QErrorMessage;
然后添加私有对象:
QErrorMessage* errordlg;
在mywidget.cpp添加头文件#include <QErrorMessage>
,并在构造函数中添加:
errordlg = new QErrorMessage(this);
最后在按钮事件中添加:
void MyWidget::on_errButton_clicked()
{
errordlg->setWindowTitle(tr("错误信息对话框"));
errordlg->showMessage(tr("这里是出错信息!"));
}
错误信息对话框中默认有一个Show this message agin
复选框,可以选择以后是否还要显示相同的错误信息;为了这个复选框的功能有效,不能像前边的例子一样在槽中直接创建对话框。
8.向导对话框
添加生成向导页的函数声明:
private:
QWizardPage* createPage1();
QWizardPage* createPage2();
QWizardPage* createPage3();
对这三个函数进行定义:
QWizardPage *MyWidget::createPage1()
{
QWizardPage* page = new QWizardPage;
page->setTitle(tr("介绍"));
return page;
}
QWizardPage *MyWidget::createPage2()
{
QWizardPage* page = new QWizardPage;
page->setTitle(tr("用户选择信息"));
return page;
}
QWizardPage *MyWidget::createPage3()
{
QWizardPage* page = new QWizardPage;
page->setTitle(tr("结束"));
return page;
}
在按钮事件中添加向导对话框:
void MyWidget::on_guideButton_clicked()
{
QWizard wizard(this);
wizard.setWindowTitle(tr("向导对话框"));
wizard.addPage(createPage1());
wizard.addPage(createPage2());
wizard.addPage(createPage3());
wizard.exec();
}
QFrame类族
QFrame 类是带有边框的部件的基类。它的子类包括QLabel、QLCDNumber、QSplitter、QStrackedWidget、QToolBox、QAbstractScrollArea类。QAbstractScrollArea 是所有带有滚动区域的部件类的抽象基类,这里需要说明,Qt中凡是带有Abstract字样的类都是抽象基类。抽象基类是不能直接使用的,但是可以继承该类实现自己的类,或者使用它提供的子类。
带边框部件最主要的特点就是可以有一个明显的边框框架。QFrame类的主要功能就是用来实现不同的边框效果,这主要是由边框形状(Shape)和边框阴影(Shadow)组合来形成的。
这里说明两个词:lineWidth和midLineWidth,其中lineWidth是边框边界线的宽度;而midLineWidth是在边框中额外插入的一条线的宽度,这条线的作用是为了形成3D效果,并且只在Box、HLine和VLine且表现为凸起或者凹陷时有用。
QLabel
alignment属性:水平的改为AlignHCenter,垂直的改为AlignVCenter,这样QLabel中的文本就会在正中间显示。
wordWrap属性:实现文本的自动换行。
文本省略
如果文本过长时不想自动换行,而是在后面自动省略,那么可以使用QFontMetrics类,该类用来计算给定字体的字符或字符串的大小,其中包含了多个实用的函数。要使用QFontMetrics类,则可以通过创建对象的方式,或通过QWidget::fontMetrics()函数返回当前部件字体的QFontMetrics对象。在构造函数中添加如下代码实现省略:
QString string = tr("标题太长,需要进行省略!");
QString str = ui->label->fontMetrics().elidedText(string, Qt::ElideMiddle, 180);
ui->label->setText(str);
QFontMetrics类的elidedText()函数用来进行文本省略,第一个参数用来指定要省略的文本;第二个参数是省略模式,就是"…"省略号出现的位置,包括Qt::ElideLeft出现在文本开头、Qt::ElideMiddle出现在文本中间,以及这里使用的Qt::ElideRight出现在文本末尾; 第三个参数是文本的长度,单位是像素,只要第一个参数指定的文本长度超过了这个值,就会进行省略。
设置静态图片
scaledContents属性:可以实现缩放标签中的内容。
添加头文件#include <QPixmap>
,然后在构造函数中添加一行代码:
ui->label->setPixmap(QPixmap("C:/tj.jpg"));
设置gif图
添加头文件#include <QMovie>
,然后在构造函数中添加代码:
QMovie* movie = new QMovie("C:/hh.gif");
ui->label->setMovie(movie);
movie->start();
QLCDNumber
smallDecimalPoint属性:显示小数点。
digitCount属性:设置显示的数字的个数。设置为7,表示显示7个数字。
mode属性:选Dec表示显示十进制数值,也可设置十六进制、八进制、二进制。
segmentStyle属性:用来设置数码管的显示样式。
QLineEdit
输入掩码
QLineEdit 提供了输入掩码(inputMask)来限制输入的内容。可以使用一些特殊的字符来设置输入的格式和内容。
void MyWidget::on_lineEdit2_returnPressed()
{
ui->lineEdit3->setFocus();
qDebug() << ui->lineEdit2->text(); //输出lineEdit2的文本内容
qDebug() << ui->lineEdit2->displayText(); //输出lineEdit2的显示的内容
}
具体参见帮助。
输入验证
在QLineEdit中还可以使用验证器(validator)来对输入进行约束。
QIntValidator:整数约束
QDoubleValidator:浮点数约束
QRegExp和QValidator:使用正则表达式约束
自动补全
QCompleter类实现自动补全。
在构造函数中添加自动完成器:
QStringList wordList;
wordList << "Qt" << "Qt Creator" << tr("你好");
QCompleter* completer = new QCompleter(wordList, this); //新建自动完成器
completer->setCaseSensitivity(Qt::CaseSensitive); //设置大小写不敏感
ui->lineEdit4->setCompleter(completer);
QAbstractSpinBox
QAbstractSpinBox 类是一个抽象基类,提供了一个数值设定框和一个行编辑器来显示设定值。它有3个子类QDateTimeEdit、QSpinBox和QDoubleSpinBox,分别用来完成日期时间、整数和浮点数的设定。
QDateTimeEdit
displayFormat:显示格式
calendarPopup:对于DateEdit,使用弹出的日历部件设置日期
QSpinBox 和 QDoubleSpinBox
suffix:后缀属性
prefix:前缀属性
mininum:最小值
maximum:最大值
singleStep:设置每次增加的数值
decimals:设置小数点后面的位数
QAbstractSlider
QAbstractSlider类用于提供区间内的一个整数值,它有一个滑块,可以定位到一个整数区间的任意值。该类是一个抽象类,它有3个子类:QScrollBar、QSlider和QDial。
ScrollBar属性:
maximun:设置最大值
minimum:设置最小值
singleStep:设置每步的步长,默认为1,就是按下方向键后其数值增加或减少
pageStep:设置每页的步长,默认是10,就是按下PageUp或者PageDown键后数值增加或减少
value和sliderPostion:当前值
tracking:设置是否跟踪,默认为是,就是在拖动滑块时,每移动一个刻度都会发射valueChanged()信号,如果选择否,只有拖动滑块释放时才发射该信号。
orientation:设置部件的方向
invertedAppearance:设置滑块所在的位置。比如滑块开始在最左端,选中这个属性后,滑块默认就会在最右端。
invertedControls设置反向控制,比如默认向上是增加,则反之。
focusPolicy:设置为StrongFocus,使部件可以获取强焦点
两个Slider属性:
tickPosition:设置刻度位置,默认不显示。
tickInterval:设置刻度间隔。
Dial属性:
wrapping:设置是否首尾相连。默认开始与结束是分开的。
notchTarget:设置刻度之间的间隔。
notchesVisible:设置是否显示刻度。