小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Qt中,當(dāng)QDockWidget的父窗口是一個(gè)不可以拖動(dòng)的QTabWidget的時(shí)候?qū)崿F(xiàn)拖動(dòng)的方法

 昵稱10504424 2015-09-02

    之前在做有關(guān)QDockWidget的內(nèi)容時(shí)候遇到了瓶頸,那就是窗口彈出來之后拖動(dòng)不了,也不可以放大和縮小,若是彈出來之后設(shè)置成了window的flags,也不可以拖動(dòng),而且也不是需要的效果。

    1.彈出來之后的dockwidget的titlebar右邊需要有3個(gè)按鈕分別來控制放大與恢復(fù)、彈出來與收進(jìn)去和關(guān)閉按鈕??紤]到Qt自帶的dockwidget彈出來后實(shí)現(xiàn)不了這個(gè),所以參考了網(wǎng)上的方法,需要自己從QWidget中派生一個(gè)類來實(shí)現(xiàn)自己的titlebar

    2.因?yàn)閐ockwidget是嵌套在QTabWidget中的,而tabwidget本身是不可以拖動(dòng)的,所以此dockwiget也不可以拖動(dòng)(Qt中子窗口的拖動(dòng)是和父窗口有關(guān)聯(lián)的),加上需要實(shí)現(xiàn)自己的dockwidget樣式,所以也從QDockWidget中派生一個(gè)類

    首先實(shí)現(xiàn)自己的titlebar:

復(fù)制代碼
 1 class myDockWidgetTitleBar:public QWidget
 2 {
 3     Q_OBJECT
 4 
 5 private:
 6     //自己需要的類成員定義
 7     QSize sizeHint() const { return minimumSizeHint(); }
 8     QSize mimimumSizeHint() const;//在寫自己的titlebar時(shí),這2個(gè)函數(shù)必須要實(shí)現(xiàn)
 9 
10 protected:
11     void paintEvent(QPaintEvent *event);
12     void mouseDoubleClickEvent(QMouseEvent *event);
13     void mouseReleaseEvent(QMouseEvent *event);
14 
15 private slots:
16     //自己定義的一些槽函數(shù),比如我這里需要實(shí)現(xiàn)放大縮小、浮動(dòng)和關(guān)閉
17     void MaxMinDockWidget();
18     void FloatDockWidget();
19     void CloseDockWidget();
20 
21 public:
22     myDockWidgetTitleBar(QWidget *parent = 0);
23     ~myDockWigetTitleBar();
24 };
復(fù)制代碼

    這里需要注意的是:若dockwidget沒有titlebar則直接setTitleBarWidget(QWidget());這樣可以只有一個(gè)dockwidget的窗口而沒有窗口上面的titlebar。(方法來源于網(wǎng)上,源地址找尋不到了,若是找到再加上原有鏈接)

    下面寫一下在實(shí)現(xiàn)titlebar時(shí)必須要實(shí)現(xiàn)的函數(shù)的實(shí)現(xiàn):

復(fù)制代碼
 1 QSize *myDockWidgetTitleBar::minimumSizeHint() const
 2 {
 3     myDockWidget*dock_widget = qobject_cast<myDockWidget *>(parentWidget());
 4     Q_ASSERT(dock_widget != 0);
 5     QSize result(50, 30);
 6     if(dock_widget->features & QDockWidget::DockWidgetVerticalTitleBar)
 7     {
 8         result.transpose();
 9     }
10     return result;
11 }
復(fù)制代碼

    paintEvent主要用來在titlebar上繪制圖標(biāo)和位置。不過我這里因?yàn)檫@些按鈕其他地方也要用到,所以我將按鈕都定義成了類成員,同時(shí)在構(gòu)造函數(shù)中給出了按鈕的類型。其他的slots函數(shù)可以根據(jù)需求定義就行。

    實(shí)現(xiàn)自己的dockwidget:

復(fù)制代碼
 1 class myDockWidget:public QDockWidget
 2 {
 3     Q_OBJECT
 4 
 5 private:
 6     //一些類成員變量
 7     int _cur_point_pos;
 8     int _margin_length;
 9     QWidget *_default_title_bar;
10     myDockWidgetTitleBar *_dock_widget_title_bar;
11 
12 protected:
13     void mouseMoveEvent(QMouseEvent *event);//因?yàn)橐獙?shí)現(xiàn)拖動(dòng),所以這個(gè)鼠標(biāo)移動(dòng)事件必須要實(shí)現(xiàn)
14     void mousePressEvent(QMouseEvent *event);//拖動(dòng)的時(shí)候鼠標(biāo)左鍵應(yīng)該是一直按壓著的,所以需要在這個(gè)里面進(jìn)行判斷
15     void mouseReleaseEvent(QMouseEvent *event);
16     void closeEvent(QCloseEvent *event);
17 
18 public:
19     myDockWidget(QTabWidget *tab_widget, QWidget *parent = 0);
20     ~myDockWidget();
21 };
復(fù)制代碼

    需要注意的是這里的類定義中都用到了Q_OBJECT,若是在類中有信號(hào)和槽函數(shù)的定義,則必須要寫此,具體的原因請(qǐng)參考Qt幫助手冊(cè)。

   上面的類中還需要定義一個(gè)用來判斷鼠標(biāo)左鍵是否一直按壓著的bool變量和鼠標(biāo)之前點(diǎn)擊的位置信息:

1 private:
2     bool _left_mose_press;
3     Qpoint _last_point_pos, _length_pos;

    鼠標(biāo)按壓事件中:

復(fù)制代碼
 1 void myDockWidget::mousePressEvent(QMouseEvent *event)
 2 {
 3     if(event->button == Qt::LeftButton)
 4     {
 5         _left_mouse_press = ture;
 6         _last_point_pos = event->globalPos();
 7         _cur_point_pos = CountFlag(event->pos(), CountColumn(event->pos()));
 8         event->ignore();
 9     }          
10 }
復(fù)制代碼

    鼠標(biāo)釋放事件中:

復(fù)制代碼
1 void myDockWidget::mouseReleaseEvent(QMouseEvent *event)
2 {
3     if(_left_mouse_press)
4     {
5          _left_mouse_press = false;
6     }
7     QApplication::restoreOverrideCursor();
8     event->ignore();   
9 }
復(fù)制代碼

    重點(diǎn)是這里的鼠標(biāo)移動(dòng)事件,這里處理的方法參考了【Qt編程】基于Qt的詞典開發(fā)系列<四>--無邊框窗口的縮放與拖動(dòng),并且這里里面有很詳細(xì)的描述:有拖動(dòng)窗口也有當(dāng)鼠標(biāo)放到四周顯示不同形狀進(jìn)行放大縮小。這里將一個(gè)窗口劃分成3*3的板塊的方法還是不錯(cuò)的。

    但是這里有一點(diǎn)不好的就是,每次拖動(dòng)的時(shí)候都會(huì)重繪,若是窗口里面的內(nèi)容比較復(fù)雜,當(dāng)鼠標(biāo)移動(dòng)過快的時(shí)候便會(huì)出現(xiàn)窗口在某一個(gè)位置停下來了。這里還需要進(jìn)一步的改進(jìn)。

    (移動(dòng)窗口本身也有很多方法,但是考慮到要支持不同的平臺(tái),可能不能夠只用到windows下的函數(shù),所以選擇了上面的方法,若只有windows平臺(tái),可以考慮下面的方法:

    1. Qt窗口拖動(dòng)及改變大小

    2. Qt 無標(biāo)題無邊框程序的拖動(dòng)和改變大小

    3. 【Qt】移動(dòng)無邊框窗體

    這些都是我當(dāng)時(shí)查找到的一些方法,其實(shí)網(wǎng)上的方法大多也都是類似的,當(dāng)然如果能夠一個(gè)一個(gè)的看demo中的例子,就會(huì)發(fā)現(xiàn)其實(shí)Qt的源代碼中也有類似的操作,網(wǎng)上的方法和Qt例子中的都大同小異)

     當(dāng)然Qt中也有獲取當(dāng)前屏幕大小的函數(shù),這個(gè)可用來處理放大和縮小的時(shí)候看要到什么大小:

1 QRect desktop_rect = QApplication::desktop()->availableGeometry();

 

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多