【问题标题】:PyQt LineEdit QAction change icon on checked/uncheckedPyQt LineEdit QAction 更改图标选中/未选中
【发布时间】:2020-07-15 11:35:36
【问题描述】:

我需要向 QLineEdit 添加一个按钮,将其设置为可检查并根据选中/未选中状态更改图标。我是这样做的:

icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(os.path.join("Images", "L.png")), QtGui.QIcon.Normal, QtGui.QIcon.On)
icon.addPixmap(QtGui.QPixmap(os.path.join("Images", "Home.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
searchActionBttn = QtWidgets.QAction("None", self.searchIn)
searchActionBttn.triggered.connect(lambda: print(searchActionBttn.isChecked()))
searchActionBttn.setCheckable(True)
searchActionBttn.setIcon(icon)
self.searchIn.addAction(searchActionBttn, QtWidgets.QLineEdit.LeadingPosition)

但是当我点击它时图标没有改变。

【问题讨论】:

    标签: python python-3.x pyqt qlineedit qaction


    【解决方案1】:

    问题是因为QAction关联的QToolButton有自己的自定义paintEvent方法所以没有考虑到checkbox的状态

    // https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qlineedit_p.cpp#n354
    void QLineEditIconButton::paintEvent(QPaintEvent *)
    {
        QPainter painter(this);
        QWindow *window = qt_widget_private(this)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);
        QIcon::Mode state = QIcon::Disabled;
        if (isEnabled())
            state = isDown() ? QIcon::Active : QIcon::Normal;
        const QLineEditPrivate *lep = lineEditPrivate();
        const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16;
        const QSize iconSize(iconWidth, iconWidth);
        const QPixmap iconPixmap = icon().pixmap(window, iconSize, state, QIcon::Off);
        QRect pixmapRect = QRect(QPoint(0, 0), iconSize);
        pixmapRect.moveCenter(rect().center());
        painter.setOpacity(m_opacity);
        painter.drawPixmap(pixmapRect, iconPixmap);
    }

    (强调我的)

    如您所见,状态仅在按下按钮时发生变化,因此应放弃使用 QAction 的选项。

    另一种选择是直接通过布局设置 QToolButton

    import os
    from functools import partial
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class LineEdit(QtWidgets.QLineEdit):
        @property
        def _internal_layout(self):
            if not hasattr(self, "_internal_layout_"):
                self._internal_layout_ = QtWidgets.QHBoxLayout(self)
            self._internal_layout_.addStretch()
            self._internal_layout_.setContentsMargins(2, 2, 2, 2)
            return self._internal_layout_
    
        def add_button(self, button):
            self._internal_layout.insertWidget(self._internal_layout.count() - 2, button)
            QtCore.QTimer.singleShot(0, partial(self._fix_cursor_position, button))
            button.setFocusProxy(self)
    
        def _fix_cursor_position(self, button):
            self.setTextMargins(button.geometry().right(), 0, 0, 0)
    
    
    app = QtWidgets.QApplication([])
    
    icon = QtGui.QIcon()
    icon.addPixmap(
        QtGui.QPixmap(os.path.join("Images", "L.png")), QtGui.QIcon.Normal, QtGui.QIcon.On
    )
    icon.addPixmap(
        QtGui.QPixmap(os.path.join("Images", "Home.png")),
        QtGui.QIcon.Normal,
        QtGui.QIcon.Off,
    )
    
    button = QtWidgets.QToolButton()
    button.setStyleSheet("border: none")
    button.setCheckable(True)
    button.setIcon(icon)
    
    searchIn = LineEdit()
    searchIn.add_button(button)
    
    searchIn.show()
    
    app.exec_()
    

    【讨论】:

      猜你喜欢
      • 2013-02-11
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多