化石原创文章,转载请注明来源并保留原文链接


Qt的上下文菜单实现方式要根据Widget的contextMenuPolicy(这是Widget的一个成员变量)来定。

1、自定义菜单

先在Widget初始化的时候调用

setContextMenuPolicy(Qt::CustomContextMenu);

指定该widget的上下文菜单是自定义的。

这里的自定义并不是说上下文菜单随意摆置内容-菜单怎么显示本来就是自定义。而是:实现上下文的方式或者说流程不同。

这里的流程是:

当上下文的行为(大多是右键点击)产生时,Qt底层会发出

 customContextMenuRequested() 

这个信号。

该信号定义在QWidget中:

 Q_SIGNALS:
     void customContextMenuRequested(const QPoint &pos);

所以,我们要能得到上下文信号,只要做一个slot就可以。

这样,自定义形式下,就三步:

a、setContextMenuPolicy(Qt::CustomContextMenu);

b、连接信号和插槽,比如:

connect(this, SIGNAL (customContextMenuRequested(const QPoint&)), this, SLOT (contextMenu(const QPoint&)));

c、在插槽里实现具体的菜单内容,位置是信号传过来的。

应用场合:

QTableView继承类的上下文菜单

2、默认上下文菜单

这个相当于用

 setContextMenuPolicy(Qt::DefaultContextMenu ); 

此种状况下,如果Widget中有重写的

void contextMenuEvent(QContextMenuEvent* event);

方法。这个方法在对应的时候就会激发。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


必须使用ico文件,最简单的ico文件生成可以通过该网站:

https://favicon.io/favicon-generator/

有了ico文件后。只要按照下面做即可:

1、放置ico文件到项目根目录(这个在项目的什么位置不强制,可以在后面改动)

2、在项目根目录写一个rc文件(这个文件位置也不强制),里面内容如下(以ico文件在根目录为例)

 IDI_ICON1          ICON   DISCARDABLE   "app.ico" 

这里ico文件的名字叫做app.ico,必须是根目录下的ico文件的全名

3、打开项目的pro文件,在后面加入

 RC_FILE += resource.rc

这里意味着我们在第二步写的rc文件全名叫做resource.rc,你可以取任何其他名字。

Windows完成。

如果是MacOS,使用如下步骤:

1、找到一个大一点的png图做图标的种子,比如512×512的,或者1024×1024的,假设名字叫pic.png

2、在该png目录,建立一个目录,名字icons.iconset

3、使用一下命令(应该是mac自带,不然就是开发命令行套件带的)

 sips -z 16 16 pic.png --out icons.iconset/icon_16x16.png
 sips -z 32 32 pic.png --out icons.iconset/icon_16x16@2x.png
 sips -z 32 32 pic.png --out icons.iconset/icon_32x32.png
 sips -z 64 64 pic.png --out icons.iconset/icon_32x32@2x.png
 sips -z 64 64 pic.png --out icons.iconset/icon_64x64.png
 sips -z 128 128 pic.png --out icons.iconset/icon_64x64@2x.png
 sips -z 128 128 pic.png --out icons.iconset/icon_128x128.png
 sips -z 256 256 pic.png --out icons.iconset/icon_128x128@2x.png
 sips -z 256 256 pic.png --out icons.iconset/icon_256x256.png
 sips -z 512 512 pic.png --out icons.iconset/icon_256x256@2x.png
 sips -z 512 512 pic.png --out icons.iconset/icon_512x512.png
sips -z 1024 1024 pic.png --out icons.iconset/icon_512x512@2x.png 

这一系列命令会在刚才建立的目录下生成各个不同只存的png图,用来做最后的icon的输入。这里不是所有的png都需要生成。

4、使用下面的命令,生成最后的图标文件

  iconutil -c icns icons.iconset -o icon.icns 

5、拷贝生成的icon.icns文件到项目的根目录

6、pro文件中加入下面的一行

ICON = icon.icns
MacOS的完成。

这里要注意的是,如果已经有了编译出的debug、release中间文件,可能一次编译并不能马上是图标生效。最有效的方式是删除这些目录,再编译,能马上看到图标生效。

参考(官方文档):

https://doc.qt.io/qt-5/appicon.html

注意这个文档中还提到了一个imagemagick工具,可以中png转化ico文件。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


做一个上下文菜单,大多菜单QAction引发的方法,都进入同一个触发方法,这样在方法中,这样能少写很多方法,代码也会简洁很多。引起的一个问题是:在这个方法中,必须知道是哪个QAction引发。

sender()方法就用来解决该问题,只要是QObject的子类,都包含该方法,这样,如果知道是QAction引发的方法调用,只要把send()返回的值强转为QAction,就能得到该QAction的text,如果text就能识别,那么就知道是哪个QAction激发了方法。

    QAction* action = qobject_cast<QAction*> (sender());
    int size = action->text().toInt();


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


Qt写应用,常见的需求是控件不是当前焦点的时候,也需要侦测按键、鼠标事件。这种需求只要使用eventFilter即可。

1、Widget头文件中,加入

protected:

     bool eventFilter(QObject *obj, QEvent *event);

2、Widget构造中,写上

qApp->installEventFilter(this);

注意,这里的qApp可以看做全局变量,实际上是个宏,在qcoreapplication.h中:

#define qApp QCoreApplication::instance()

这里使用qApp的原因是只要应用是焦点,那么该Widget就能得到事件,不管层级、不管控件自身是否有焦点。

3、具体的过滤方法大致样子

bool TextExplorer::eventFilter(QObject *obj, QEvent *e) {
    if (e->type() == QEvent::KeyPress) {
        QKeyEvent* event = (QKeyEvent*) e;
        if (event->key() == Qt::Key_Right) {
            
        }
        else if(event->key() == Qt::Key_Left) {
           
        }
    }
}

化石原创文章,转载请注明来源并保留原文链接