QT學習(五)----360界面製做(2終結)

繼續上一章的360新特性界面。源代碼:http://download.csdn.net/detail/zhangyang1990828/5241242安全

上一章中實現了整個界面的純UI設計,此次咱們讓它生動起來。函數

QT學習(五)oop

首先讓「360安全桌面」「木馬防火牆」..這四個按鈕「動」起來。學習

讓這個按鈕有幾種狀態:ui

①鼠標進入時變成低亮高透明this

②鼠標離開時恢復原狀spa

③鼠標點擊後變成高亮低透明.net

爲了實現這幾種狀態,須要三個事件和兩個變量:設計

enterEvent(QEvent* e);blog

leaveEvent(QEvent* e);

mousePressEvent(QMouseEvent* e);

m_mousePressFlag;

m_mouseEnterFlag;

經過這三個事件和兩個變量,就能夠實現按鈕的幾種狀態了。(還須要經過信號槽來實現只有一個按鈕被選中)

代碼:

 

[cpp]  view plain copy
 
  1. connect(label, SIGNAL(signalLabelPress(CLabel*)), this, SLOT(slotLabelButtonPress(CLabel*)));  
[cpp]  view plain copy
 
  1. void DataBrain::slotLabelButtonPress(CLabel *label)  
  2. {  
  3.     for (int i = 0; i < WINDOW_BUTTON_COUNT; i++)  
  4.     {  
  5.         if (label != m_pLabelBtnArray[i])  
  6.         {  
  7.             m_pLabelBtnArray[i]->setMousePressFlag(false);  
  8.         }  
  9.     }  
  10. }  



 

 

[cpp]  view plain copy
 
  1. //按鈕特效  
  2. void CLabel::setMouseEnterFlag(bool flag)  
  3. {  
  4.     m_mouseEnterFlag=flag;  
  5.     this->update();  
  6. }  
  7. void CLabel::setMousePressFlag(bool flag)  
  8. {  
  9.     m_mousePressFlag=flag;  
  10.     this->update();  
  11. }  
  12. bool CLabel::getMouseEnterFlag()  
  13. {  
  14.     return m_mouseEnterFlag;  
  15. }  
  16. bool CLabel::getMousePressFlag()  
  17. {  
  18.     return m_mousePressFlag;  
  19. }  
  20. void CLabel::enterEvent(QEvent *e)  
  21. {  
  22.     if(!getMousePressFlag())  
  23.     {  
  24.         setMouseEnterFlag(true);  
  25.     }  
  26.     this->setCursor(Qt::PointingHandCursor);//設置鼠標的形狀  
  27. }  
  28. void CLabel::leaveEvent(QEvent *e)  
  29. {  
  30.     setMouseEnterFlag(false);  
  31. }  
  32. void CLabel::mousePressEvent(QMouseEvent *e)  
  33. {  
  34.     if(e->button()==Qt::LeftButton)  
  35.     {  
  36.         setMousePressFlag(true);  
  37.         emit signalLabelPress(this);  
  38.     }  
  39. }  

效果圖:

 


ok!咱們繼續來實現右上角關閉按鈕的動態的效果。

和上面的相同,關閉的按鈕也是須要三個狀態:

 

①鼠標進入時

②鼠標離開時

③鼠標點擊後

不一樣的是,關閉按鈕不是對按鈕設置樣式,而是對它進行更換圖片。

這裏值得一提的是,這裏用的eventFilter(事件過濾器),對某個控件install一個eventFiler後,能夠在eventFilter的事件中經過傳遞進來的兩個參數(QObject*,QEvent*)來對事件進行控制。

十分簡單,上代碼:

 

[cpp]  view plain copy
 
  1. //關閉按鈕的效果  
  2. void DataBrain::createEventFilter()  
  3. {  
  4.     m_pCloseBtn->installEventFilter(this);  
  5. }  
  6. bool DataBrain::eventFilter(QObject *target , QEvent *event)  
  7. {  
  8.     EButtonMouseState state=EButtonMouseNone;  
  9.   
  10.     if(target==m_pCloseBtn)  
  11.     {  
  12.         if(event->type()==QEvent::Enter)  
  13.         {  
  14.             state=EButtonMouseEnter;  
  15.         }  
  16.         else if(event->type()==QEvent::Leave)  
  17.         {  
  18.             state=EButtonMouseDefault;  
  19.         }  
  20.         else if(((QMouseEvent*)event)->button()==Qt::LeftButton)  
  21.         {  
  22.             if(event->type()==QEvent::MouseButtonPress)  
  23.             {  
  24.                 state=EButtonMousePress;  
  25.             }  
  26.             else if (event->type()==QEvent::MouseButtonRelease)  
  27.             {  
  28.                 state = EButtonMouseEnter;  
  29.             }  
  30.         }  
  31.         if(state!=EButtonMouseNone)  
  32.         {  
  33.             setButtonIcon((QToolButton*)target,state);  
  34.         }  
  35.     }  
  36.     return QWidget::eventFilter(target, event);  
  37. }  
  38. void DataBrain::setButtonIcon(QToolButton *btn, EButtonMouseState state)  
  39. {  
  40.     QPixmap pixmap(":/images/images/btn_close.png");  
  41.     int nWidth = pixmap.width()/4;  
  42.     int nHeight = pixmap.height();  
  43.     btn->setIcon(QIcon(pixmap.copy(QRect(state*nWidth, 0, nWidth, nHeight))));  
  44.     btn->setIconSize(QSize(nWidth, nHeight));  
  45. }  
[cpp]  view plain copy
 
  1. connect(m_pCloseBtn,SIGNAL(clicked()),qApp,SLOT(quit()));//給按鈕加上關閉程序的功能  

效果圖:

 


最後來實現窗口的推拽功能(點擊串口上的一部份內能夠拖動窗口)和主頁面選擇頁的拖拽(頁面選擇以及按鈕選擇的變換)

這裏是整個設計中最複雜的地方!

首先須要先肯定要完成窗口拖拽和主頁面選擇須要抽象出幾個方法,怎樣劃分這些方法

①鼠標被按下事件mousePressEvent,在這裏須要去判斷鼠標的左鍵和右鍵,左鍵的話按下的區域是在窗口拖拽區仍是在主頁選擇區,這裏須要注意的是,關閉按鈕也在窗口拖拽區,須要在關閉按鈕的的點擊事件將窗口拖拽的flag設置成false。完成這個類須要m_mouseMoveWindowFlag(窗口是否能被拖拽的flag),m_mousePressFlag(主窗口可否被拖拽的flag)兩個flag;右鍵的話判斷當前的主頁面是否能向左滾動,須要setLabelMove和getLabelMove進行設置和讀取m_labelMoveFlag來對主頁面能被向左移仍是向右移進行flag。m_labelMoveFlag=flase能向右移不能向左移,m_labelMoveFlag=true能向左移不能向右移。(這裏的左移和右移指的是整頁的移動)

②鼠標移動的事件mouseMoveEvent,在這裏須要進行判斷m_mouseMoveWindowFlag和m_mousePressFlag,經過這兩個標識去完成是進行窗口的移動仍是主頁面的拖拽。(這裏須要注意的是,這裏的移動是拖拽,須要進行不斷的事件響應,才能出現拖拽的效果。)

③鼠標的按鍵釋放事件mouseReleaseEvent,在這裏須要對m_mouseMoveWindowFlag和m_mousePressFlag進行判斷,看剛結束的鼠標按鍵按下和釋放過程當中作了什麼,若是m_mousePressFlag=true,則幹才進行了主頁面的拖拽,須要經過鼠標按鍵按下時鼠標的座標和釋放時鼠標的座標來進行判斷鼠標拖拽的方向,再經過moveCurrentPage(整頁移動的函數)來完成頁面的滾動;若是m_mousePressFlag=false,則剛纔進行了窗口移動事件,須要在這裏從新將m_mouseMoveWindowFlag設置成false。

③整頁移動的函數moveCurrentPage,經過起始點的座標和終點的座標來判斷滾動的方向。若是沒有鼠標的拖動,而是經過鼠標右鍵或者快捷鍵來實現的頁面滾動,則直接進行頁面滾動。

④拖拽主頁面到新的頁面時,須要用改變當前選擇按鈕的函數changeCurrentButton,須要在這裏調用CButton的setMousePressFlag函數從新對選中按鈕進行設定。

⑤slotChangeCurrentPage函數,須要對點擊按鈕的事件進行響應,點擊按鈕則主頁面進行響應的滾動

⑥快捷鍵的響應keyPressEvent,這裏對快捷鍵進行設置。

OK!明白了以上的就能夠了,代碼:

 

[cpp]  view plain copy
 
  1. //窗口拖拽  
  2. void DataBrain::mousePressEvent(QMouseEvent *e)  
  3. {  
  4.     if(e->button()==Qt::LeftButton)  
  5.     {  
  6.         m_mouseSrcPos=e->pos();  
  7.         if(m_mouseSrcPos.y()<=40)  
  8.         {  
  9.             m_mouseMoveWindowFlag=true;  
  10.         }  
  11.         else  
  12.         {  
  13.             m_currentFgXpos=m_pLabelFg->x();  
  14.             m_mousePressFlag=true;  
  15.         }  
  16.     }  
  17.     //右鍵左移  
  18.     else if(e->button()==Qt::RightButton)  
  19.     {  
  20.         if(getLabelMove())  
  21.         {  
  22.             if(m_currentFgIndex>0)  
  23.             {  
  24.                 m_currentFgIndex--;  
  25.                 moveCurrentPage(false);  
  26.             }  
  27.         }  
  28.     }  
  29. }  
  30. inline void DataBrain::setLabelMove(bool enable)  
  31. {  
  32.     m_labelMoveFlag = enable;  
  33. }  
  34.   
  35. inline bool DataBrain::getLabelMove()  
  36. {  
  37.     return m_labelMoveFlag;  
  38. }  
  39. void DataBrain::moveCurrentPage(bool direction)  
  40. {  
  41.     int currentXpos = 0;//當前label的x座標  
  42.     int destXpos = 0;//目標x座標  
  43.   
  44.     //改變當前頁面對應的按鈕  
  45.     changeCurrentButton();  
  46.   
  47.     //圖片的幾個分割點  
  48.     //0-680, 680-1360, 1360-2040, 2040-2720  
  49.     //真:向左移;  假:向右移  
  50.     if (direction)  
  51.     {  
  52.         //左移的幾種可能性,對於x座標  
  53.         //index=0, 將label移動到-680*0  
  54.         //index=1, 將label移動到-680*1  
  55.         //index=2, 將label移動到-680*2  
  56.         //index=3, 將label移動到-680*3  
  57.         setLabelMove(false);  
  58.         currentXpos = m_pLabelFg->x();  
  59.         destXpos = -WINDOW_WIDTH * m_currentFgIndex;  
  60.         while(currentXpos > destXpos)//平滑滾動效果  
  61.         {  
  62.             m_pLabelFg->move(currentXpos-WINDOW_PAGE_MOVE, WINDOW_START_Y);  
  63.             currentXpos = m_pLabelFg->x();  
  64.             qApp->processEvents(QEventLoop::AllEvents);//依然保持監聽事件  
  65.         }  
  66.         m_pLabelFg->move(destXpos, WINDOW_START_Y);//確保最後移到指定的位置  
  67.         setLabelMove(true);  
  68.     }  
  69.     else  
  70.     {  
  71.         //右移的幾種可能性,對於x座標,與左移一致  
  72.         //index=0, 將label移動到-680*0  
  73.         //index=1, 將label移動到-680*1  
  74.         //index=2, 將label移動到-680*2  
  75.         //index=3, 將label移動到-680*3  
  76.         setLabelMove(false);  
  77.         currentXpos = m_pLabelFg->x();  
  78.         destXpos = -WINDOW_WIDTH * m_currentFgIndex;  
  79.         while(currentXpos < destXpos)  
  80.         {  
  81.             m_pLabelFg->move(currentXpos+WINDOW_PAGE_MOVE, WINDOW_START_Y);  
  82.             currentXpos = m_pLabelFg->x();  
  83.             qApp->processEvents(QEventLoop::AllEvents);  
  84.         }  
  85.         m_pLabelFg->move(destXpos, WINDOW_START_Y);  
  86.         setLabelMove(true);  
  87.     }  
  88. }  
  89. void DataBrain::changeCurrentButton()  
  90. {  
  91.     for (int i = 0; i < WINDOW_BUTTON_COUNT; i++)  
  92.     {  
  93.         if (i != m_currentFgIndex)  
  94.         {  
  95.             m_pLabelBtnArray[i]->setMousePressFlag(false);  
  96.         }  
  97.         else  
  98.         {  
  99.             m_pLabelBtnArray[i]->setMousePressFlag(true);  
  100.         }  
  101.     }  
  102. }  
  103. void DataBrain::slotChangeCurrentPage(CLabel *label)  
  104. {  
  105.     int index = 0;  
  106.   
  107.     for (int i = 0; i < WINDOW_PAGE_COUNT; i++)  
  108.     {  
  109.         if (label == m_pLabelBtnArray[i])  
  110.         {  
  111.             index = i;  
  112.             break;  
  113.         }  
  114.     }  
  115.   
  116.     //移動的幾種可能性,對於x座標  
  117.     //index=0, 將label移動到-680*0  
  118.     //index=1, 將label移動到-680*1  
  119.     //index=2, 將label移動到-680*2  
  120.     //index=3, 將label移動到-680*3  
  121.     //點擊左邊的按鈕 右移  
  122.     if (index < m_currentFgIndex)  
  123.     {  
  124.         while(index != m_currentFgIndex)  
  125.         {  
  126.             m_currentFgIndex--;  
  127.             moveCurrentPage(false);  
  128.         }  
  129.     }  
  130.     else if (index > m_currentFgIndex) //點擊右邊的按鈕 左移  
  131.     {  
  132.         while(index != m_currentFgIndex)  
  133.         {  
  134.             m_currentFgIndex++;  
  135.             moveCurrentPage(true);  
  136.         }  
  137.     }  
  138. }  
  139. void DataBrain::mouseMoveEvent(QMouseEvent *e)  
  140. {  
  141.     int x = 0;  
  142.   
  143.     if (m_mousePressFlag)  
  144.     {  
  145.         if (getLabelMove())  
  146.         {  
  147.             m_mouseDstPos = e->pos();  
  148.             x = m_mouseDstPos.x() - m_mouseSrcPos.x();  
  149.   
  150.             setLabelMove(false);  
  151.             m_pLabelFg->move(m_currentFgXpos + x, WINDOW_START_Y);  
  152.             setLabelMove(true);  
  153.         }  
  154.     }  
  155.     else if (m_mouseMoveWindowFlag)  
  156.     {  
  157.         m_mouseDstPos = e->pos();  
  158.         this->move(this->pos() + m_mouseDstPos - m_mouseSrcPos);  
  159.     }  
  160. }  
  161. void DataBrain::mouseReleaseEvent(QMouseEvent *e)  
  162. {  
  163.     int xpos = 0;  
  164.   
  165.     if (m_mousePressFlag)  
  166.     {  
  167.         if (getLabelMove())  
  168.         {  
  169.             m_mouseDstPos = e->pos();  
  170.   
  171.             xpos = m_mouseDstPos.x() - m_mouseSrcPos.x();  
  172.   
  173.             if (xpos > 0)//右移  
  174.             {  
  175.                 if (xpos >= WINDOW_ONEBUTTON_WIDTH)  
  176.                 {  
  177.                     if (m_currentFgIndex > 0)  
  178.                     {  
  179.                         m_currentFgIndex--;  
  180.                         moveCurrentPage(false); //右移  
  181.                     }  
  182.                     else  
  183.                     {  
  184.                         moveCurrentPage(true); //左移  
  185.                     }  
  186.                 }  
  187.                 else  
  188.                 {  
  189.                     moveCurrentPage(true); //左移  
  190.                 }  
  191.             }  
  192.             else //左移  
  193.             {  
  194.                 if (xpos <= -WINDOW_ONEBUTTON_WIDTH)  
  195.                 {  
  196.                     if (m_currentFgIndex < WINDOW_PAGE_COUNT-1)  
  197.                     {  
  198.                         m_currentFgIndex++;  
  199.                         moveCurrentPage(true); //左移  
  200.                     }  
  201.                     else  
  202.                     {  
  203.                         moveCurrentPage(false); //右移  
  204.                     }  
  205.                 }  
  206.                 else  
  207.                 {  
  208.                     moveCurrentPage(false); //右移  
  209.                 }  
  210.             }  
  211.   
  212.             m_mousePressFlag = false;  
  213.         }  
  214.     }  
  215.     else if (m_mouseMoveWindowFlag)  
  216.     {  
  217.         m_mouseMoveWindowFlag = false;  
  218.     }  
  219. }  
  220. //快捷鍵  
  221. void DataBrain::keyPressEvent(QKeyEvent *e)  
  222. {  
  223.     if (getLabelMove())  
  224.     {  
  225.         switch(e->key())  
  226.         {  
  227.         case Qt::Key_Left:  
  228.         case Qt::Key_Up:  
  229.             if (m_currentFgIndex > 0)  
  230.             {  
  231.                 m_currentFgIndex--;  
  232.                 moveCurrentPage(false); //右移  
  233.             }  
  234.             break;  
  235.   
  236.         case Qt::Key_Right:  
  237.         case Qt::Key_Down:  
  238.             if (m_currentFgIndex < WINDOW_PAGE_COUNT-1)  
  239.             {  
  240.                 m_currentFgIndex++;  
  241.                 moveCurrentPage(true); //左移  
  242.             }  
  243.             break;  
  244.   
  245.         default:  
  246.             break;  
  247.         }  
  248.     }  
  249. }  

代碼有點長,須要所有代碼的能夠去 http://download.csdn.net/detail/zhangyang1990828/5241242下載源代碼。效果圖就不上了,和360的新特性差很少。

 

經過這樣一個例子,我想對於整個Qt的機制有了必定的瞭解吧,之後有好例子還會與你們分享的。

相關文章
相關標籤/搜索