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

來源:互聯網
上載者:User

1.畫關閉按鈕
拖動圖片的功能放後面說,先把關閉按鈕給畫出來。
現在很多軟體,類似QQ,360,91助手......等等軟體,介面上都有很多很漂亮的按鈕,當滑鼠移上去,按鈕變為高亮,當滑鼠點擊下去,按鈕變為暗色凹下,當滑鼠移開,按鈕又恢複原來的樣子。
這效果都是由多張圖片切換而來的。

new出一個QToolButton,設定關閉按鈕表徵圖。按鈕圖片一般都以4種狀態提供,將4張圖片拼成1張png。所以每次只需取出圖片中的1/4就行,然後將關閉按鈕移動到右上方。

想在Qt中實現這3種效果,很簡單,只需在表單中安裝事件過濾器即可。
涉及到函數:eventFilter, installEventFilter.
幾種按鈕的enum:

enum EButtonMouseState{    EButtonMouseDefault = 0,    EButtonMouseEnter,    EButtonMousePress,    EButtonMouseNone};void Preview360::createEventFilter(){    //安裝事件過濾器    m_pButtonClose->installEventFilter(this);}//設定按鈕表徵圖void Preview360::setButtonIcon(QToolButton *btn, EButtonMouseState state){    QPixmap pixmap(":/images/btn_close.png");    int nWidth = pixmap.width()/4;    int nHeight = pixmap.height();    btn->setIcon(QIcon(pixmap.copy(QRect(state * nWidth, 0, nWidth, nHeight))));    btn->setIconSize(QSize(nWidth, nHeight));}bool Preview360::eventFilter(QObject *target, QEvent *event){    EButtonMouseState state = EButtonMouseNone;    //對幾種事件進行處理,這下載對Qt的事件過濾器,很清楚了,實踐結合理論=...    if (target == m_pButtonClose)    {        if (event->type() == QEvent::Enter)        {            state = EButtonMouseEnter;        }        else if (event->type() == QEvent::Leave)        {            state = EButtonMouseDefault;        }        else if (((QMouseEvent *)event)->button() == Qt::LeftButton)        {            if (event->type() == QEvent::MouseButtonPress)            {                state = EButtonMousePress;                //若點擊在關閉按鈕上,不拖動映像                m_mousePressFlag = false;            }            else if (event->type() == QEvent::MouseButtonRelease)            {                state = EButtonMouseDefault;            }        }        if (state != EButtonMouseNone)        {            setButtonIcon((QToolButton *)target, state);        }    }    //處理完自訂攔截的事件,還要調用一次QWidget預設的事件過濾函數    return QWidget::eventFilter(target, event);}


2.表單的移動

表單和圖片的移動涉及到滑鼠事件,只需事件滑鼠的一些事件就可以達到預期的效果,主要的事件是:

void mousePressEvent(QMouseEvent *);void mouseReleaseEvent(QMouseEvent *);void mouseMoveEvent(QMouseEvent *);


3.圖片的移動
在操作上,有3個涉及到圖片的移動:
(1).滑鼠拖動圖片
(2).滑鼠拖動圖片後,釋放滑鼠,圖片恢複原位
(3).右鍵滑鼠,圖片右移
(4).鍵盤方向鍵控製圖片的移動
(5).點擊介面的4個按鈕,分別移動到按鈕對應的介面

4.關於滑鼠控制的移動
這些主要是涉及到一些邏輯的代碼,直接貼出:

void Preview360::mousePressEvent(QMouseEvent *e){    if (e->button() == Qt::LeftButton)    {        m_mouseSrcPos = e->pos();        //在y座標小於40的地區,滑鼠拖動使表單移動        if (m_mouseSrcPos.y() <= 40)        {            m_mouseMoveWindowFlag = true;        }        else        {        //大於40的地區,滑鼠拖動使圖片移動            m_currentFgXpos = m_pLabelFgTotal->x();            m_mousePressFlag = true;        }    }    //右鍵滑鼠,右移圖片    else if (e->button() == Qt::RightButton)    {        if (getLabelMove())        {            if (m_currentFgIndex > 0)            {                m_currentFgIndex--;                moveCurrentPage(false); //右移            }        }    }}void Preview360::mouseReleaseEvent(QMouseEvent *e){    int xpos = 0;    if (m_mousePressFlag)    {        if (getLabelMove())        {            m_mouseDstPos = e->pos();            xpos = m_mouseDstPos.x() - m_mouseSrcPos.x();            if (xpos > 0)//右移            {                if (xpos >= WINDOW_ONEBUTTON_WIDTH)                {                    if (m_currentFgIndex > 0)                    {                        m_currentFgIndex--;                        moveCurrentPage(false); //右移                    }                    else                    {                        moveCurrentPage(true); //左移                    }                }                else                {                    moveCurrentPage(true); //左移                }            }            else //左移            {                if (xpos <= -WINDOW_ONEBUTTON_WIDTH)                {                    if (m_currentFgIndex < WINDOW_PAGE_COUNT-1)                    {                        m_currentFgIndex++;                        moveCurrentPage(true); //左移                    }                    else                    {                        moveCurrentPage(false); //右移                    }                }                else                {                    moveCurrentPage(false); //右移                }            }            m_mousePressFlag = false;        }    }    else if (m_mouseMoveWindowFlag)    {        m_mouseMoveWindowFlag = false;    }}void Preview360::mouseMoveEvent(QMouseEvent *e){    int x = 0;    if (m_mousePressFlag)    {        if (getLabelMove())        {            m_mouseDstPos = e->pos();            x = m_mouseDstPos.x() - m_mouseSrcPos.x();            setLabelMove(false);            m_pLabelFgTotal->move(m_currentFgXpos + x, WINDOW_START_Y);            setLabelMove(true);        }    }    else if (m_mouseMoveWindowFlag)    {        m_mouseDstPos = e->pos();        this->move(this->pos() + m_mouseDstPos - m_mouseSrcPos);    }}


5.點擊介面4個按鈕進行移動

void Preview360::slotChangeCurrentPage(CLabel *label){    int index = 0;    for (int i = 0; i < WINDOW_PAGE_COUNT; i++)    {        if (label == m_pLabelBtnArray[i])        {        //找出當前按鈕的序號            index = i;            break;        }    }    //移動的幾種可能性,對於x座標    //index=0, 將label移動到-680*0    //index=1, 將label移動到-680*1    //index=2, 將label移動到-680*2    //index=3, 將label移動到-680*3    //點擊左邊的按鈕 右移    if (index < m_currentFgIndex)    {        while(index != m_currentFgIndex)        {            m_currentFgIndex--;            moveCurrentPage(false);        }    }    else if (index > m_currentFgIndex) //點擊右邊的按鈕 左移    {        while(index != m_currentFgIndex)        {            m_currentFgIndex++;            moveCurrentPage(true);        }    }    else    {        //...    }}


6.鍵盤方向鍵的控制
捕捉對應的按鍵事件,只需重新實現鍵盤事件:
void keyPressEvent(QKeyEvent *);
左上鍵:圖片右移
右下鍵:圖片左移

void Preview360::keyPressEvent(QKeyEvent *e){    if (getLabelMove())    {        switch(e->key())        {        case Qt::Key_Left:        case Qt::Key_Up:            if (m_currentFgIndex > 0)            {                m_currentFgIndex--;                moveCurrentPage(false); //右移            }            break;        case Qt::Key_Right:        case Qt::Key_Down:            if (m_currentFgIndex < WINDOW_PAGE_COUNT-1)            {                m_currentFgIndex++;                moveCurrentPage(true); //左移            }            break;        default:            break;        }    }}


7.圖片移動的關鍵函數
移動圖片的具體函數,要緩慢的移動圖片,也就是在迴圈裡面延遲一下,並響應UI事件,防止介面凍結(未響應)。
在程式中,出現setLabelMove和getLabelMove函數,這兩個函數主要是用來防止多個事件同時移動介面,導致錯誤。所以這裡相當於給圖片的移動加鎖,保證移動操作的唯一性。

void Preview360::moveCurrentPage(bool direction){    int currentXpos = 0;//當前label的x座標    int destXpos = 0;//目標x座標    //改變當前頁面對應的按鈕    changeCurrentButton();    //圖片的幾個分割點    //0-680, 680-1360, 1360-2040, 2040-2720    //真:向左移;  假:向右移    if (direction)    {        //左移的幾種可能性,對於x座標        //index=0, 將label移動到-680*0        //index=1, 將label移動到-680*1        //index=2, 將label移動到-680*2        //index=3, 將label移動到-680*3        setLabelMove(false);        currentXpos = m_pLabelFgTotal->x();        destXpos = -WINDOW_WIDTH * m_currentFgIndex;        while(currentXpos > destXpos)        {            m_pLabelFgTotal->move(currentXpos-WINDOW_PAGE_MOVE, WINDOW_START_Y);            currentXpos = m_pLabelFgTotal->x();            qApp->processEvents(QEventLoop::AllEvents);        }        m_pLabelFgTotal->move(destXpos, WINDOW_START_Y);        setLabelMove(true);    }    else    {        //右移的幾種可能性,對於x座標,與左移一致        //index=0, 將label移動到-680*0        //index=1, 將label移動到-680*1        //index=2, 將label移動到-680*2        //index=3, 將label移動到-680*3        setLabelMove(false);        currentXpos = m_pLabelFgTotal->x();        destXpos = -WINDOW_WIDTH * m_currentFgIndex;        while(currentXpos < destXpos)        {            m_pLabelFgTotal->move(currentXpos+WINDOW_PAGE_MOVE, WINDOW_START_Y);            currentXpos = m_pLabelFgTotal->x();            qApp->processEvents(QEventLoop::AllEvents);        }        m_pLabelFgTotal->move(destXpos, WINDOW_START_Y);        setLabelMove(true);    }}

防止介面凍結:
qApp->processEvents(QEventLoop::AllEvents);
該函數用來處理所有事件,保證了介面的正常運行。

8.將控制項置頂
在最後補充下,要將需要的控制項raise到棧頂:

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

多個控制項涉及到重疊的問題,只有這樣重新調整棧順序才能達到需要的效果。

源碼:360新版特性介面

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.