Qt:QLabel、LCD Number、QProgressBar、QCalendarWidget

目录

一、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)
    {
        //休眠1s
        std::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)
        {
            //休眠1s
            std::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

表示一个日历

属性

 

 

常见信号

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值