目录
一、QLabel
1.属性
2.设置文本格式
3.设置图片
4.设置文本对齐方式
5.设置自动换行
6.设置缩进
7.设置边距
8.设置伙伴关系
二、LCD Number
1.属性
2.Qt仅允许主线程修改界面
三、QProgressBar
属性
四、QCalendarWidget
属性
一、QLabel
同样的,QLabel也是QWidget的子控件,QWidget拥有的属性同样适用于QLabel。
QLabel也有众多属性,主要用来显示文字信息,属于显示类控件。
1.属性
用于获取其中的文本。
QLabel->text();
QLabel->textFormat();
获取文本的格式,Qt中文本的格式可以是以下几种。
1.Qt::PlainText纯文本。
2.Qt::RichText富文本,即文本中支持html标签等,富文本可以理解为word工具编辑中的文件。
3.Qt::MarkdownText 即MD格式的文本。
4.Qt::AutoText 根据文本内容自动决定文本格式。
QLabel->pixmap();
可以设置QLable内中包含的图片。
QLabel->scaledContents();
是否拉伸填充,true 或者false,往往在QLabel中有图片时设置。
QLabel->alignment();
设置QLabel中文本的对齐方式,常见的有居中、靠左。
QLabel->wordWrap();
设置QLabel中长文本是否要自动换行,因为不同于QTextEdit这样的控件,QLabel不含滚动条。
QLabel->indent();
设置文本缩进。
QLabel->margin();
设置内部文本和边框的边距。
QLabel->openExternalLinks();
如果QLabel中包含一段url,设置是否允许点击访问。
QLabel->buddy();
给QLabel关联一个伙伴,点击QLabel即可激发伙伴,如关联QCheckBox,点击则选中它。
2.设置文本格式
ui->label->setTextFormat(Qt::PlainText);ui->label->setText("<b>这是一段纯文本</b>");ui->label_2->setTextFormat(Qt::RichText);ui->label_2->setText("<b>这是一段富文本</b>");ui->label_3->setTextFormat(Qt::MarkdownText);ui->label_3->setText("# 这是MD的一级标题");
演示效果:
3.设置图片
//设置Label的尺寸和窗口一样大QRect windowRect = this->geometry();ui->label->setGeometry(0,0,windowRect.width(),windowRect.height());//设置Label中的图片QPixmap pixmap(":/R-C.jpg");ui->label->setPixmap(pixmap);//设置图片拉伸填充ui->label->setScaledContents(true);
但是在构造函数中的设置是一次性的,在后续拖动窗口大小时,标签的尺寸并不会发生改变,于是,就有下面这样的现象:
要想让图片大小跟随窗口尺寸的变化,实现这样一个效果,需要用到Qt中的事件机制。
Qt中对于用户的操作分为了两类,这两类分别是信号槽机制、事件机制。
如何理解这两种机制,本质上是离散变量和连续变量的区分,在Qt中,类似于鼠标点击这样的操作,一次点击、两次点击.....是可以枚举的,属于离散变量,Qt用信号槽机制来处理,而对于拖动窗口变化尺寸这样的操作,比如从A尺寸变化到B尺寸,本质上经过了一系列的尺寸变化,并不是直接由A变到B,对于这种连续的变化,Qt用事件机制来处理。
而对于窗口尺寸的变化,Qt用resizeEvent函数来处理,QWidget定义了该函数,而现在要想让窗口尺寸的变化按照程序员的想法实现,需要重写QWidget中的虚函数,实际上,在框架编程中,Qt可以通过多态的方式来调用程序员重写的函数,并不需要程序员来调用。
在widget.h中添加声明
void resizeEvent(QResizeEvent *event) override;
void Widget::resizeEvent(QResizeEvent *event)
{//打印观察变化中的窗口尺寸qDebug() << event->size();//设置QLabel的尺寸变化跟随窗口ui->label->setGeometry(0,0,event->size().width(),event->size().height());
}
4.设置文本对齐方式
//水平、垂直方向都居中。
ui->label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
5.设置自动换行
ui->label->setWordWrap(true);
6.设置缩进
ui->label->setIndent(50);//缩进50个像素
在Qt中,这样设置缩进后,如果文本换行,也是会缩进的,不仅仅是首行会缩进。
7.设置边距
ui->label->setMargin(50);
//边距是上下左右都留出对应的像素,如果文本长,则牺牲文本的显示效果。
8.设置伙伴关系
ui->label->setBuddy(ui->radioButton);ui->label_2->setBuddy(ui->radioButton_2);
可以通过按下 Alt + A、Alt+B的快捷键选中单选框。
二、LCD Number
1.属性
定时器功能:
C++标准库没有实现定时器的功能,但是Boost实现了,可以使用。同样的,Qt也实现了定时器功能,利用的是信号槽机制。QTimer类的对象可以发出timeout的信号,在start方法中设置参数,这个参数用来说明:QTimer类的对象每隔几秒发出timeout的信号,而每次发出信号,就去执行槽函数,从而实现倒计时的程序。
timer = new QTimer(this);//timeout信号绑定槽函数connect(timer,&QTimer::timeout,this,&Widget::handle);//设置每隔几秒发送信号timer->start(1000);
void Widget::handle()
{//先获取当前的值int value = ui->lcdNumber->intValue();if(value <= 0){timer->stop();}else{ui->lcdNumber->display(value -1);}
}
2.Qt仅允许主线程修改界面
上述倒计时程序使用QTimer来实现了定时器,那么是否可以使用C++标准库中的函数,使得每隔一秒,就更新一次界面呢。
那么怎么用C++标准库实现休眠一秒。
在C++98中,是没有这样的函数的,但是在C++11中,有一个函数叫做sleep_for
在头文件<thread>中,有一个this_thread的命名空间,其中实现了一个sleep_for的函数。
在头文件<chrono>中,有一个类名为seconds,用来表示秒,是类模板duration实例化出来的类。
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//先获取初始值int val = ui->lcdNumber->intValue();while(true){//休眠1sstd::this_thread::sleep_for(std::chrono::seconds(1));if(val <= 0)break;val -=1;ui->lcdNumber->display(val);}
}
这段代码实际上,只有计数结束才会显示LCD Number,因为我们把倒计时的操作写在了Widget的构造函数中,当构造函数执行完毕,倒计时也结束,所以只显示了最终结果。
于是,设计这样一种做法,在构造函数中,新启一个线程执行上述操作,主线程做展示界面,而新线程做倒计时,是否可行呢?
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);std::thread t([this](){//先获取初始值int val = this->ui->lcdNumber->intValue();while(true){//休眠1sstd::this_thread::sleep_for(std::chrono::seconds(1));if(val <= 0)break;val -=1;this->ui->lcdNumber->display(val);}});
}
然后实际运行启动后,控制台打印了一条日志。
对于Qt这样的GUI框架,需要专门维护一个线程用来更新界面,就是main函数所在的进程,即主线程,而一个界面中,存在很多隐藏的状态,Qt为了更新界面时,不引发线程安全问题,直接禁用了Qt中的其他线程修改界面,于是,我们上面自己新启的线程会被直接中止。
默认情况下,调用槽函数的都是主线程。
在main.cpp中的 return a.exec();
执行a.exec()后,主线程就会进入“事件循环”的状态,exec()内部是一个死循环,每一次循环,都在执行一些操作。
三、QProgressBar
属性
表示一个进度条
我们设置一个程序,每隔100ms进度条就加一
void Widget::handle()
{int value = ui->progressBar->value();if(value >= 100)timer->stop();ui->progressBar->setValue(value+1);
}
可以设置进度条的颜色。
四、QCalendarWidget
表示一个日历
属性
常见信号