目錄
一、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
表示一個日歷
屬性
?
?
常見信號
?
?