【问题标题】:Change QPushButton Icon on hover and pressed在悬停并按下时更改 QPushButton 图标
【发布时间】:2017-03-12 03:41:19
【问题描述】:

我正在尝试在悬停并按下时更改 QpushButton 的图标,我正在使用带有样式表的 QtDesigner。 我试过这个

QpushButton{
       qproperty-icon:url(:/images/start.png);
}

QPushButton:hover
{
       qproperty-icon:url(:/images/start_hov.png);
}

但它不起作用。

I tried setting it from QtDesigner Menu 但效果不佳。

【问题讨论】:

    标签: qt qt-designer qstylesheet


    【解决方案1】:

    我认为值得一提的是,截至发布此答案时,已批准答案中提到的错误似乎已得到修复。我的按钮有以下样式表宏。这使得按钮图标在悬停并按下时可以正确更改。

    #define BUTTON_STYLESHEET_TEMPLATE(not_pressed, hovered, pressed) "QPushButton {"\
    "border-image: url(:icons/" not_pressed ");"\
    "background-repeat: no-repeat;"\
    "width: 65px;"\
    "height: 56px;"\
    "}"\
    "QPushButton:hover {"\
    "border-image: url(:icons/" hovered ");"\
    "}"\
    "QPushButton:pressed {"\
    "border-image: url(:icons/" pressed ");"\
    "}"
    

    我使用 setStyleSheet 函数将它应用于我的每个 QPushButton,将每个状态的三个不同图像传递到宏中。

    button.setStyleSheet(BUTTON_STYLESHEET_TEMPLATE("not_pressed.png", "hovered.png", "pressed.png"));
    

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      不幸的是,它是一个bug of Qt,仍然没有修复。该错误的 cmets 中有一个 workaround suggestion,基本上您可以使用空的 qproperty-icon 并保留必要的空间,同时实际更改 background-image 属性:

      QPushButton {
          qproperty-icon: url(" "); /* empty image */
          qproperty-iconSize: 16px 16px; /* space for the background image */
          background-image: url(":/images/start.png");
          background-repeat: no-repeat;
      }
      
      QPushButton:hover {
          background-image: url(":/images/start_hov.png");
          background-repeat: no-repeat;
      }
      

      但最终的结果看起来……真的不是很令人满意。如果您在运行时使用 C++ 更改按钮的图标,您可以获得更好的结果,这里有一个使用事件过滤器的简单示例:

      #include <QObject>
      #include <QPushButton>
      #include <QEvent>
      
      class ButtonHoverWatcher : public QObject
      {
          Q_OBJECT
      public:
          explicit ButtonHoverWatcher(QObject * parent = Q_NULLPTR);
          virtual bool eventFilter(QObject * watched, QEvent * event) Q_DECL_OVERRIDE;
      };
      
      ButtonHoverWatcher::ButtonHoverWatcher(QObject * parent) :
          QObject(parent)
      {}
      
      bool ButtonHoverWatcher::eventFilter(QObject * watched, QEvent * event)
      {
          QPushButton * button = qobject_cast<QPushButton*>(watched);
          if (!button) {
              return false;
          }
      
          if (event->type() == QEvent::Enter) {
              // The push button is hovered by mouse
              button->setIcon(QIcon(":/images/start_hov.png"));
              return true;
          }
      
          if (event->type() == QEvent::Leave){
              // The push button is not hovered by mouse
              button->setIcon(QIcon(":/images/start.png"));
              return true;
          }
      
          return false;
      }
      

      然后在您的代码中的某个地方设置 UI,您可以执行以下操作:

      ButtonHoverWatcher * watcher = new ButtonHoverWatcher(this);
      ui->pushButton->installEventFilter(watcher);
      

      还有宾果游戏 - 您会在悬停和取消悬停时看到按钮的图标发生变化!

      【讨论】:

      • QIcon 对象最多可以包含 4 个图像,具体取决于模式。在创建时设置这些图像,然后让 Qt 完成剩下的工作不是更容易吗?
      • 我无法使用这种方法,topicstarter 也没有尝试从 Qt Designer 设置图标图像。您能否通过另一个答案提供这种方法的工作示例?
      【解决方案3】:

      我知道这是一个老问题,但我认为它可能仍然有用。

      为了获得一个默认只显示图像的按钮,然后在悬停时显示不同的图像,我尝试在编辑器中设置一个图标并使用onSelectedonActive 等,但自然而然地,它没用。

      工作的灵感来自@JosephFarrish 和@goerge,因此首先归功于他们。我决定将我的答案发布为“有形”的解决方案。

      对于特定的按钮,我有 2 张图片:

      • 默认显示

      • 然后开启悬停效果

      针对特定 QPushButton 的解决方案是:

      QPushButton {
          border-image: url(:/icons/ic-explore);
          background-repeat: no-repeat;
          width: 32px;
          height: 32px;
      }
      
      QPushButton:hover {
          border-image: url(:/icons/ic-explore-hover);
          background-repeat: no-repeat;
      }
      

      如您所见,ic-exploreic-explore-hover 已添加到我的资源文件中,如下所示:

      实际图标位于项目根文件夹中的一个名为 icons 的文件夹中。图标的前缀由:/icons/ 给出,恰好与icons 文件夹名称相同。

      请注意我设置了 QPushButton 的宽度和高度的 CSS。

      【讨论】:

        【解决方案4】:

        阅读本文后遇到类似问题。这是我在 C++ 中的工作,不使用设计师的样式表。

        1>我创建一个用于被按下的图标和一个用于正常的图标。在您的情况下,我们会将其称为悬停条件。

        2>将图标添加到资源文件中。

        3>参考下面的代码...

        Add_PB 是一个 QPushButton。

        Add_PB->setStyleSheet( "*{border-image: url(:/icons/maximize.bmp);}"  
        ":pressed{ border-image: url(:/icons/maximize_pressed.bmp);}"); 
        

        这里的关键是您可以使用 setStyleSheet 为不同的条件设置不同的图标。在 CSS 字符串中使用 * 运算符或“通用选择器”之前,我无法让上述代码工作。

        参考:http://doc.qt.io/qt-5/stylesheet-syntax.html

        【讨论】:

          【解决方案5】:

          在c++中,我们可以用下面的代码来实现:

          ui->button->setStyleSheet("QPushButton{border-image : url(./default_Img.png);} QPushButton:hover{border-image : url(./hover_Img.png); }"
                                         "QPushButton:focus{border-image : url(./focus_Img.png);}");
          

          【讨论】:

          • 这不是 c++,而是缺少 Qt 功能的解决方法。这些模式位图不是样式,根本不应该通过 StyleSheet 设置。
          【解决方案6】:

          我在设计器中制作了它,来自 ui_...h 文件:

          QIcon icon;
          icon.addFile(QStringLiteral(":/unpressed.png"), QSize(), QIcon::Normal, QIcon::Off);
          icon.addFile(QStringLiteral(":/pressed.png"), QSize(), QIcon::Normal, QIcon::On);
          pushButton->setIcon(icon);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-10-11
            • 2021-01-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多