简体   繁体   English

PyQt:可以为 QPushButton 分配一个 QAction 吗?

[英]PyQt: Can a QPushButton be assigned a QAction?

Using Python 3.2x and PyQT 4.8x:使用 Python 3.2x 和 PyQT 4.8x:

I initialized an action and assigned to a menu item:我初始化了一个动作并分配给一个菜单项:

self.__actionOpen = QtGui.QAction(self.__mw)
self.__actionOpen.setObjectName("actionOpen")
self.__actionOpen.setText("OpenFile")
QtCore.QObject.connect(self.__actionOpen, QtCore.SIGNAL("triggered()"), self.__accessFile)
self.__menuFile.addAction(self.__actionOpen)

Works fine - menu item is there with caption "OpenFile" and the action signal/slot is invoked.工作正常 - 菜单项带有标题“OpenFile”并调用动作信号/插槽。

I tried it with a QPushButton - same QAction object:我用 QPushButton 尝试过 - 相同的 QAction 对象:

self.__buttonFile.addAction(self.__actionOpen)

Nothing: No caption on the button, nothing happens when it's clicked.无:按钮上没有标题,单击时没有任何反应。

Do actions not work with QButton (the addAction call did not complain...)? QButton 不能使用动作(addAction 调用没有抱怨......)? Or is there something wrong with my code?还是我的代码有问题? Perhaps the "triggered()" signal is not appropriate for an action that interacts with QPushButton?也许“triggered()”信号不适合与 QPushButton 交互的动作?

You can't assign a QAction to a QPushButton the way you want.您不能以您想要的方式将QAction分配给QPushButton QPushButton doesn't redefine addAction so the behavior comes from QWidget.addAction which adds the action to the context menu of the button. QPushButton没有重新定义addAction ,因此行为来自QWidget.addAction ,它将操作添加到按钮的上下文菜单中。

You can however assign the action to a QToolButton with setDefaultAction which will change the button caption and trigger the action when clicked.但是,您可以使用setDefaultAction将操作分配给QToolButton ,这将更改按钮标题并在单击时触发操作。

Or you could do it manually anyway by subclassing QPushButton and adding a setDefaultAction method that would change everything in the button according to the action (caption, tooltip...) and connects the relevant button's signals to the action's slots.或者,您可以通过QPushButton并添加一个setDefaultAction方法来手动执行此操作,该方法将根据操作(标题、工具提示...)更改按钮中的所有内容,并将相关按钮的信号连接到操作的插槽。

Adding an action won't "run" the action when the button is clicked, and that is by design.单击按钮时,添加操作不会“运行”该操作,这是设计使然。

If what you are after is to reuse or refer the QAction's behaviour you can just connect the clicked() signal of the QPushButton to the trigger() of the QAction :如果您要重用或参考 QAction 的行为,您只需将QPushButtonclicked()信号连接到QActiontrigger()

QtCore.QObject.connect(self.__menuFile,
                       QtCore.SIGNAL("clicked()"),
                       self.__actionOpen.trigger)

That way the self.__actionOpen action will be triggered whenever the self.menuFile button is clicked.这样,只要单击self.menuFile按钮,就会触发self.__actionOpen操作。

You could create a PushButtonAction:您可以创建一个 PushButtonAction:

h file: h 文件:

#ifndef PUSHBUTTONACTION_H
#define PUSHBUTTONACTION_H
#include <QAction>
#include <QPushButton>

class PushButtonAction: public QPushButton
{
    Q_OBJECT
public:
    PushButtonAction(QAction *action, QWidget *parent = 0);
};

#endif // PUSHBUTTONACTION_H

cpp file: cpp文件:

#include "pushbuttonaction.h"

PushButtonAction::PushButtonAction(QAction *action, QWidget *parent):
    QPushButton(parent)
{
    setIcon(action->icon());
    setText(action->text());
    connect(this, SIGNAL(clicked()), action, SLOT(trigger()));
}

My solution for this issue:我对这个问题的解决方案:

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QPushButton

class QActingPushButton(QPushButton):
    """QPushButtons don't interact with their QActions. This class triggers
    every `QAction` in `self.actions()` when the `clicked` signal is emitted.
    https://stackoverflow.com/a/16703358
    """
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.clicked.connect(self.trigger_actions)

    @pyqtSlot()
    def trigger_actions(self) -> None:
        for act in self.actions():
            act.trigger()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM