Qt日記(2)-360新版特性介面實現(2)

來源:互聯網
上載者:User

1.UI的結構
開始畫圖形介面,首先確定UI的大小,找到360新版特性介面的皮膚,可以看到:
4個不同的頁面的像素為:680 * 370
而最頂層的一層透明頁面像素為:680 * 372

QSize(680, 370):

QSize(680, 372):

現在可以確定下來,UI的大小為(680, 372);但4個頁面只在370個像素空間中運動,最上面空餘的為透明地區,其中在X軸(20-100)的矩形地區,為半透明效果的地區,這些均為圖片貼出。下面給個:

在圖中,2個像素空間中,紅色地區使用Qt中的setMask函數來遮掩,綠色矩形地區為要顯示的圖片部分,此為半透明效果。
所以剩下的所有控制項均活動在矩形:點(0, 2) -> 點(680, 372)空間中。

在這張圖中,畫出了UI的設計架構,具體還是根據程式進行調整最佳位置。

2.畫出最基本的背景圖
只需重新實現QWidget的paintEvent事件,就可以達到上述所說的效果:

void Preview360::paintEvent(QPaintEvent *){    QBitmap bitmap(this->size());    QPainter painter(&bitmap);    painter.fillRect(bitmap.rect(), Qt::white);    painter.setBrush(QColor(0, 0, 0));    //填充一個以圓弧為4個角的矩形,使表單的四個角變成圓弧    painter.drawRoundedRect(QRect(0, 2, this->width(), this->height()-2), 5, 5);    //畫出(0, 2) -> (2, 100)地區    painter.drawRoundedRect(QRect(20, 0, 120-20, 2), 2, 2);    setMask(bitmap);}

代碼很簡單,關鍵在於setMask函數的使用。
若要在一個矩形視窗中央畫一個圓,以下步驟:
(1).先畫出表單
(2).在表單大小的矩形QBitmap中以白色填充整張圖
(3).在矩形中央以黑色畫一個圓,用黑色填充這個圓
(4).setMask(bitmap)
此時效果就出來了,一個不規則表單,圓。

這時候再加入圖片,最基本的背景圖就出來了。
new出2個QLabel標籤來存放圖片:

m_pLabelBg0 = new QLabel(this);m_pLabelBg0->setPixmap(QPixmap(":/images/bg_bottom.png"));m_pLabelBg0->setGeometry(QRect(0, 2, this->width(), this->height()-2));m_pLabelBg1 = new QLabel(this);m_pLabelBg1->setPixmap(QPixmap(":/images/bg_top.png"));m_pLabelBg1->setGeometry(QRect(0, 0, this->width(), this->height()));

bg_top.png這張圖必須置頂,Qt表單中是基於堆棧表單的,只需將m_pLabelBg1提升到棧頂即可,Qt提供了一個函數:raise。

m_pLabelBg1->raise();

當然這裡涉及到很多控制項的排序(棧排序),所以待所有控制項都初始化完成後,再來控制也不遲。

3.畫出4個頁面
這裡使用的方法是將4張圖畫到一個QLabel中的方法,該方法比較簡單。

QPixmap pixmap(QSize(this->width()*WINDOW_PAGE_COUNT, WINDOW_HEIGHT-2));QPainter painter(&pixmap);for (int i = 0; i < WINDOW_PAGE_COUNT; i++){    painter.drawImage(QRect(WINDOW_WIDTH*i, 0, WINDOW_WIDTH, WINDOW_HEIGHT-2),                      QImage(tr(":/images/desktop_%1.jpg").arg(i)));}m_pLabelFgTotal = new QLabel(this);m_pLabelFgTotal->resize(pixmap.size());m_pLabelFgTotal->setPixmap(pixmap);m_pLabelFgTotal->move(WINDOW_START_X, WINDOW_START_Y);

ok,現在樣子基本上差不多了。

4.建立自訂山寨按鈕
這4個按鈕並不是標準的按鈕,只需子類化QWidget,在QWidget中添加2個QLabel,一個存放圖片,一個存放文本,就能做出這種效果來,來看看:

,可以看出要實現幾個功能:
(1).2個QLabel的布局。
(2).實現滑鼠3個事件:enterEvent, leaveEvent, mousePressEvent。
(3).重新實現paintEvent事件,繪製不同的效果。
(4).滑鼠移動到該地區,改變滑鼠指標形狀。
至於第(2)點,
enterEvent:滑鼠進入該地區,背景變透明模糊
leaveEvent:滑鼠離開該地區,背景恢複正常
mousePressEvent:滑鼠點擊該地區,背景變透明模糊,明顯。
繪製背景透明模糊的效果:

void CLabel::paintEvent(QPaintEvent *e){    QPainter painter(this);    if (getMouseEnterFlag())    {        paintWidget(50, &painter);    }    else if (getMousePressFlag())    {        paintWidget(80, &painter);    }    QWidget::paintEvent(e);}void CLabel::paintWidget(int transparency, QPainter *device){    QPen pen(Qt::NoBrush, 1);    device->setPen(pen);    //漸層線    QLinearGradient linear(this->rect().topLeft(), this->rect().bottomLeft());    //設定前景色彩;    //0:前景色彩; 0.5:中間色; 1:背景色;    //transparency為透明度    linear.setColorAt(0, QColor(255, 255, 255, transparency));    QBrush brush(linear);    device->setBrush(brush);    device->drawRoundedRect(this->rect(), 2, 2);}


滑鼠的幾個事件:

void CLabel::enterEvent(QEvent *e){    if (!getMousePressFlag())    {        setMouseEnterFlag(true);    }    this->setCursor(Qt::PointingHandCursor);}void CLabel::leaveEvent(QEvent *e){    setMouseEnterFlag(false);}void CLabel::mousePressEvent(QMouseEvent *e){    if (e->button() == Qt::LeftButton)    {        setMousePressFlag(true);        emit signalLabelPress(this);    }}


5.設定樣式
其實用函數也能設定,但我發現用css文法來編輯樣式挺方便的,以後會專門來介紹樣式的使用,正因為她的實用。
在CLabel中,用如下樣式來設定字型和背景

this->setStyleSheet("QWidget {background:transparent;border:0px;color:white;font-weight:bold;font-size:16px;}");

6.畫出4個按鈕
在Preview360類中,建立4個按鈕:

QStringList nameList;//為了對齊,所以在文字後面加了空格nameList << tr("360安全案頭 ")         << tr("木馬防火牆   ")         << tr("360保鏢     ")         << tr("電腦門診     ");for (int i = 0; i < WINDOW_BUTTON_COUNT; i++){    CLabel *label = new CLabel(this);    label = new CLabel(this);    label->resize(QSize(155, 45));    label->setPixmap(QPixmap(tr(":/images/btn_%1.png").arg(i)));    label->setText(nameList.at(i));    label->move(8+i*170, 319);    connect(label, SIGNAL(signalLabelPress(CLabel*)), this, SLOT(slotLabelButtonPress(CLabel*)));;    connect(label, SIGNAL(signalLabelPress(CLabel*)), this, SLOT(slotChangeCurrentPage(CLabel*)));    m_pLabelBtnArray[i] = label;}m_pLabelBtnArray[0]->setMousePressFlag(true);

將4個CLabel按鈕提升到棧頂:

for (int i = 0; i < WINDOW_BUTTON_COUNT; i++){    m_pLabelBtnArray[i]->raise();}

但CLabel被press時,只能一個按鈕為被press狀態:

void Preview360::slotLabelButtonPress(CLabel *label){    for (int i = 0; i < WINDOW_BUTTON_COUNT; i++)    {        if (label != m_pLabelBtnArray[i])        {            m_pLabelBtnArray[i]->setMousePressFlag(false);        }    }}


360新版特性介面

其實這些東西都很簡單,沒什麼好說的。
下一篇文章繼續說明4張漂亮圖的移動和表單移動。。。

作者  : gzshun.
E-Mail: gzshuns#163.com (@)
轉載請註明出處:http://blog.csdn.net/gzshun/article/details/7596542

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.