• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            zhonghua

            C++博客 首頁 新隨筆 聯系 聚合 管理
              72 Posts :: 1 Stories :: 4 Comments :: 0 Trackbacks

            QWidget及其子類都可有右鍵菜單,因為QWidget有以下兩個與右鍵菜單有關的函數:

            Qt::ContextMenuPolicy contextMenuPolicy () const

            void setContextMenuPolicy ( Qt::ContextMenuPolicy policy )

            Qt::ContextMenuPolicy枚舉類型包括:Qt::DefaultContextMenu, Qt::NoContextMenu, Qt::PreventContextMenu, Qt::ActionsContextMenu, and Qt::CustomContextMenu。

            使用方式如下:


            1)默認是Qt::DefaultContextMenu。
            它 是利用右鍵菜單事件contextMenuEvent()來處理(which means the contextMenuEvent() handler is called)。就是要重寫contextMenuEvent( QContextMenuEvent * event )函數。


            2)使用Qt::CustomContextMenu。
            它是發出QWidget::customContextMenuRequested信號,注意僅僅只是發信號,意味著要自己寫顯示右鍵菜單的slot。
            這個信號是QWidget唯一與右鍵菜單有關的信號(也是自有的唯一信號),同時也是很容易被忽略的signal:

            void customContextMenuRequested ( const QPoint & pos )

            該信號的發出條件是:用戶請求contextMenu(常規就是鼠標右擊啦)且同時被擊的widget其contextMenuPolicy又是Qt::CustomContextMenu。
            注 意:pos是該widget接收右鍵菜單事件的位置,一般是在該部件的坐標系中。但是對于QAbstratScrollArea及其子類例外,是對應著其 視口viewport()的坐標系。如常用的QTableView、QHeaderView就是QAbstratScrollArea的子類。
            因為僅發信號,所以需自己寫顯示右鍵菜單的slot來響應,例如一個表格(QTableView類型)表頭的顯示右鍵菜單槽:
            datatable->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
            connect(datatable->horizontalHeader(), SIGNAL(customContextMenuRequested(const QPoint&)),
                    this, SLOT(show_contextmenu(const QPoint&)));//this是datatable所在窗口
            QMenu *cmenu = NULL;
            show_contextmenu(const QPoint& pos)
            {
                if(cmenu)//保證同時只存在一個menu,及時釋放內存
                {
                    delete cmenu;
                    cmenu = NULL;
                }
                QMenu cmenu = new QMenu(datatable->horizontalHeader());
               
                QAction *ascendSortAction = cmenu->addAction("升序");
                QAction *descendSortAction = cmenu->addAction("降序");
                QAction *filterAction = cmenu->addAction("過濾");
                QAction *reshowAction = cmenu->addAction("重載");
               
                connect(ascendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_ascend()));
                connect(descendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_descend()));
                connect(filterAction, SIGNAL(triggered(bool)), this, SLOT(show_filter_dlg()));
                connect(reshowAction, SIGNAL(triggered(bool)), this, SLOT(reshow_data()));
               
                cmenu->exec(QCursor::pos());//在當前鼠標位置顯示
                //cmenu->exec(pos)是在viewport顯示
            }

            也可先做好cmenu,好處是始終使用一個:
                QMenu cmenu = new QMenu(datatable->horizontalHeader());
               
                QAction *ascendSortAction = cmenu->addAction("升序");
                QAction *descendSortAction = cmenu->addAction("降序");
                QAction *filterAction = cmenu->addAction("過濾");
                QAction *reshowAction = cmenu->addAction("重載");
               
                connect(ascendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_ascend()));
                connect(descendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_descend()));
                connect(filterAction, SIGNAL(triggered(bool)), this, SLOT(show_filter_dlg()));
                connect(reshowAction, SIGNAL(triggered(bool)), this, SLOT(reshow_data()));
            show_contextmenu(const QPoint& pos)
            {
                if(cmenu)
                {
                    cmenu->exec(QCursor::pos());
                }
            }


            3)使用Qt::ActionsContextMenu。
            把部件的所有action即QWidget::actions()作為context menu顯示出來。
            還是上面的例子,要在表格(QTableView類型)表頭顯示右鍵菜單:
                    QAction *ascendSortAction = new QAction("升序", this);
                    QAction *descendSortAction = new QAction("降序", this);
                    QAction *filterAction = new QAction("過濾", this);
                    QAction *unfilterAction = new QAction("取消過濾", this);
               
                    connect(ascendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_ascend()));
                    connect(descendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_descend()));
                    connect(filterAction, SIGNAL(triggered(bool)), this, SLOT(filter_table()));
                    connect(unfilterAction, SIGNAL(triggered(bool)), this, SLOT(unfilter_table()));
               
                    datatable->horizontalHeader()->addAction(ascendSortAction);
                    datatable->horizontalHeader()->addAction(descendSortAction);
                    datatable->horizontalHeader()->addAction(filterAction);
                    datatable->horizontalHeader()->addAction(unfilterAction);
                    
                    datatable->horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);

            另外兩個就是不顯示context menu了:
            Qt::NoContextMenu
                the widget does not feature a context menu, context menu handling is deferred to the widget's parent.
               
            Qt::PreventContextMenu
                the widget does not feature a context menu, and in contrast to NoContextMenu, the handling is not deferred to the widget's parent. This means that all right mouse button events are guaranteed to be delivered to the widget itself through mousePressEvent(), and mouseReleaseEvent().

            補充:
                使用Qt::ActionsContextMenu比較簡潔,但是如果需要根據當前菜單彈出的位置來定義不同菜單,或者像上個例子,在表格 (QTableView類型)表頭顯示右鍵菜單時,我需要知道是哪一列表頭被點擊,從而在后來調用sort_ascend()排序函數時能夠根據不同列進 行不同排序策略,那么Qt::ActionsContextMenu就做不到了。
                這種需要捕捉彈出位置的情況只好用Qt::ActionsContextMenu了,customContextMenuRequested ( const QPoint & pos )信號返回點擊位置pos(在表頭視口坐標系中位置),然后表頭即可調用logicalIndexAt(pos)函數得到被點擊section對應的 index即被點擊部分的列號,然后存下來可供后面action激活的排序槽使用。
            show_contextmenu(const QPoint& pos)
            {
                //get related column of headerview
                contextmenu_column = datatable->horizontalHeader()->logicalIndexAt(pos);

                //show contextmenu
                if(cmenu)
                {
                    cmenu->exec(QCursor::pos());
                }
            }

            posted on 2012-06-01 16:25 米米 閱讀(914) 評論(0)  編輯 收藏 引用 所屬分類: qt
            一本一本久久aa综合精品| 久久婷婷五月综合色奶水99啪| 久久久久久a亚洲欧洲aⅴ| 久久99国产精品99久久| 国产69精品久久久久99| 一本一道久久a久久精品综合| 亚洲国产精品高清久久久| 99精品久久久久久久婷婷| 伊人久久大香线蕉综合5g| 久久中文骚妇内射| 精品人妻伦一二三区久久| 欧美va久久久噜噜噜久久| 久久精品国产精品亚洲| 久久国产乱子伦免费精品| 久久受www免费人成_看片中文| 国产成人无码久久久精品一| 无码人妻久久一区二区三区蜜桃| 国产成人久久精品一区二区三区 | 免费精品99久久国产综合精品| 青青国产成人久久91网| 色狠狠久久AV五月综合| 久久强奷乱码老熟女网站| 久久久久中文字幕| 99久久久精品免费观看国产| 老男人久久青草av高清| 久久这里只有精品视频99| 伊人久久精品线影院| 久久99国产综合精品免费| 亚洲va中文字幕无码久久不卡| 少妇久久久久久被弄到高潮| 久久久久人妻一区精品| 国产精品免费看久久久香蕉| 久久精品免费观看| 狠狠色婷婷综合天天久久丁香 | 一本久久久久久久| 国内精品久久久久影院免费| 亚洲精品国产美女久久久 | 国产日产久久高清欧美一区| 国产精品久久久亚洲| 久久91精品国产91久久小草| 欧美亚洲国产精品久久蜜芽|