PyQt4在TextEdit控件中创建右键菜单

原创 2014年08月17日 00:23:23

今天开发界面遇到一个问题,想将textedit的显示内容及时清空,但是由于系统自带的菜单没有清空功能,就需要自己添加该部分内容。

查了很多资料:

大致分为两种方法:

1.一种是修改父窗口Widget的menu方法,添加整体的右键菜单,然后继承父类;通过捕捉右击鼠标的动作设定响应函数。

2.第二种是重写子类的右键菜单,但是需要设定两个参数:

self.textBrowser.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
 self.textBrowser.customContextMenuRequested.connect(self.showTextContextMe)

CustomContextMenu:保持通用菜单设置;

customContextMenuRequested:当有右击鼠标的动作时,弹出菜单,

showTextContextMe:显示位置函数


实际编程中,存在矛盾,如果完全继承父类菜单,修改子类菜单时需要重新设定父类菜单的功能,实现起来比较繁琐;

但是菜单内容可以自己设置。


编写位置显示函数时遇到以下效果区别:

方法一:

      #将菜单在当前位置显示       
#        self.TextContextMenu.move(QtGui.QCursor.pos()) 
#        self.TextContextMenu.show()  
     方法二:
        #在当前坐标下显示,但是菜单停止不走动
        self.TextContextMenu.exec_(QtGui.QCursor.pos())        
        
        #将菜单在右上方显示
#        self.TextContextMenu.move(self.pos() + pos)  


以下是参考的内容,转载过来作为标记:

转自:http://blog.csdn.net/yuanzhangmei1/article/details/7724077



最近在看C++ GUI  Qt4部分其中有个例子对于扩展一个应用程序提供一个上下文菜单,其中该程序只是定义一个变量来实现其中用到了一个函数(下文会给予解答)。但是更高级的是重新定义事件处理函数void contextMenuEvent(QContextMenuEvent *event)。下面讲解其contextMenuEvent(QContextMenuEvent *event)。

 

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 )函数。

例子(该例子即是我改写的)

  1. <span style="font-size:18px;">void MainWindow::contextMenuEvent(QContextMenuEvent *event)  
  2. {  
  3.   
  4.     Context = new QMenu();  
  5.     Context->addAction(ui->actionCut);  
  6.     Context->addAction(ui->actionCope);  
  7.     Context->addAction(ui->actionPase);  
  8.     spreadsheet->setContextMenuPolicy(Qt::DefaultContextMenu);  
  9.     Context->exec(QCursor::pos());  
  10. }</span>  

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());
    }
}


此外还有一篇文章:


http://blog.sina.com.cn/s/blog_7c4674df0100xnmu.html

pyqt 创建右键菜单

(2012-01-26 19:05:21)
标签:

杂谈

分类: Python
  1. #coding=utf-8  
  2.   
  3. import sys  
  4.   
  5. from PyQt4 import QtGui  
  6. from PyQt4.QtCore import Qt  
  7.   
  8. class MainWindow(QtGui.QMainWindow):  
  9.     def __init__(self):  
  10.         super(MainWindow, self).__init__()  
  11.         self.createContextMenu()  
  12.   
  13.   
  14.     def createContextMenu(self):  
  15.         ''''' 
  16.         创建右键菜单 
  17.         '''  
  18.         必须将ContextMenuPolicy设置为Qt.CustomContextMenu  
  19.         否则无法使用customContextMenuRequested信号  
  20.         self.setContextMenuPolicy(Qt.CustomContextMenu)  
  21.         self.customContextMenuRequested.connect(self.showContextMenu)  
  22.   
  23.         创建QMenu  
  24.         self.contextMenu QtGui.QMenu(self 
  25.         self.actionA self.contextMenu.addAction(u'动作A' 
  26.         self.actionB self.contextMenu.addAction(u'动作B' 
  27.         self.actionC self.contextMenu.addAction(u'动作C' 
  28.         将动作与处理函数相关联  
  29.         这里为了简单,将所有action与同一个处理函数相关联,  
  30.         当然也可以将他们分别与不同函数关联,实现不同的功能  
  31.         self.actionA.triggered.connect(self.actionHandler)  
  32.         self.actionB.triggered.connect(self.actionHandler)  
  33.         self.actionB.triggered.connect(self.actionHandler)  
  34.   
  35.   
  36.     def showContextMenu(selfpos):  
  37.         ''''' 
  38.         右键点击时调用的函数 
  39.         '''  
  40.         菜单显示前,将它移动到鼠标点击的位置  
  41.         self.contextMenu.move(self.pos() pos)  
  42.         self.contextMenu.show()  
  43.   
  44.   
  45.     def actionHandler(self):  
  46.         ''''' 
  47.         菜单中的具体action调用的函数 
  48.         '''  
  49.         print 'action handler'  
  50.   
  51.   
  52. if __name__=='__main__' 
  53.     app QtGui.QApplication(sys.argv)  
  54.     window MainWindow()  
  55.     window.show()  
  56.     sys.exit(app.exec_())  

QListWidget 对象的创建这里不在阐述。本文以载入UI为实例

# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtCore import pyqtSignature

class Ui_formDialog(QtGui.QDialog):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)
        uic.loadUi("
form.ui", self)        #form.ui  QT界面文件 QListWidget对象名为 listView1
        self.
listDataBind()                  #添加QListWidgetItme
        self.
listView1.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)   #定义右键菜单
        
    def 
listDataBind(self):
        item = ['OaK','Banana','Apple','Orange','Grapes','Jayesh']
        for lst in item:
            self.
listView1.addItem(QtGui.QListWidgetItem(lst))
   

    #激活菜单事件
   @pyqtSignature("QPoint")
    def on_
listView1_customContextMenuRequested(self, point):
        item = self.
listView1.itemAt(point)
        #
空白区域不显示菜单
        if item != None:

           self.rightMenuShow()


    #
创建右键菜单
    def rightMenuShow(self):
        rightMenu = QtGui.QMenu(self.
listView1)
        removeAction = QtGui.QAction(u"
删除", self, triggered=self.close)       # triggered 为右键菜单点击后的激活事件。这里slef.close调用的是系统自带的关闭事件。
        rightMenu.addAction(removeAction)
        
        addAction = QtGui.QAction(u"
添加", self, triggered=self.addItem)       # 也可以指定自定义对象事件
        rightMenu.addAction(addAction)
        rightMenu.exec_(QtGui.QCursor.pos())
       

    def addItem(self):
        pass




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

PyQt4 QTextBrowser 使用教程

PyQt4 QTextBrowser 使用教程   2009-09-24 21:04:10|  分类: Linux 、windows |字号 订阅 browser = Q...
  • pi9nc
  • pi9nc
  • 2013-11-19 23:42
  • 13762

pyqt4 label点击事件,label贴图

#-*- coding:utf-8 -*- #pyqt4 label 控件设置label图标,获取点击事件 ####label本身是没有点击功能的,因此我们需要将其重载,重载,我们也可以给他加上别的功...

PyQt给QLabel添加双击事件

PyQt给QLabel添加双击事件

PyQt 右键菜单的实现(Qt.CustomContextMenu方式)

从Qt文档Qt::ContextMenuPolicy的值可以看出,实现右键菜单的方式有三种,这对于所有继承于QWidget的类都是通用的,在用每一种方式实现之前都要调用QWidget::setCont...

PyQt按钮右键菜单

第一是按钮的自定义,第二是右键菜单的使用,不仅是按钮的右键菜单,其他一些控件的右键菜单也可以类似创建和使用。 关于右键菜单则是QMenu的一些使用方法有:菜单的样式表,右键菜单的创建,右键菜单的显示位...

QT笔记(3)——Qt的lineEdit和textEdit的右键菜单汉化

关于Qt一些控件鼠标右键菜单汉化的问题,网上有一些方法,试了一下,这里做一下总结: 1、汉化需要“.qm”这个文件,这个如果深入的话可以学习一下Qt的Linguist,这个网上很多;如果只做右键菜单汉...

Pyqt5右键菜单

右键菜单的位置: self.RightMenu.exec_(QCursor.pos())

WPf 带滚动条WrapPanel 自动换行 和控件右键菜单

-->

c#GroupBox控件添加右键菜单

1.首先GroupBox控件默认没有鼠标事件的,需要在窗体加载时手动添加鼠标事件,这里添加的是MouseDown事件 private void 人力资源主界面_Load(object sender, ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)