如何将图标放置到QLineEdit上?

19

在stackoverflow.com网站的右上角有一个带放大镜图标和灰色"search"关键字的搜索框:

图片描述

我想知道是否可以使用QLineEdit实现相同的外观。如果可以,怎样做呢?


3
有几种方法可以做到这一点,但我认为一个简单的方法是在 QFrame 中添加 QLabel 和 QLineEdit,从 QLineEdit 中移除边框并使其背景透明。然后将 pixmap 设置到标签中。接着设置帧样式和 QFrame 对象的背景颜色即可。应该很简单。 - thuga
可能是重复的问题:如何在QLineEdit中插入按钮?[pyqt4] - Trilarion
7个回答

22

17

白痴式的简单方法

  1. 添加一个QLineEdit,并通过QLineEdit :: setFrame设置无边框
  2. 使用样式表在背景颜色为白色的QLabel中添加图标
  3. 使用布局将行编辑和标签组合在一起,将间距设置为0
  4. 使用QLineEdit :: setPlaceholderText设置占位文本

结果

输入图像描述 here


高级方法

查看此线程:"Can QLineEdit do this?"

以及相关的Python代码:http://bazaar.launchpad.net/~henning-schroeder/%2Bjunk/qtwidgets/annotate/head:/qtwidgets/lineedit.py

或者

"How to do - inside in QLineEdit insert the button.[pyqt4]"

基本上,通过在其上绘制小部件(标签、按钮甚至组合框)来自定义QLineEdit。然后重新设置边距、光标、填充和绘图事件。没有任何魔法!


1
我可能更喜欢先采用简单的方法。不清楚高级方法看起来或反应是否更好,但它更加复杂。简单的方法可能是更好的方法。 - Trilarion
@Trilarion:我完全同意。使用第二种解决方案,你最终会复制布局代码,在你的代码库中增加了一个特殊类,并且失去了灵活性。 如果你想在右侧添加额外的图标怎么办? 我认为这也展示了“现代”GUI的问题所在,以及它们为什么如此臃肿:对于相同的一般想法(即上下文菜单、列表和表视图、可停靠窗口小部件等),有太多特殊情况。功能几何是一种更好的方法,我希望这个想法在实践中得到更广泛的采用... - ftl

17

以下是一种更简单的替代方法:

placeholderText 设置为 "",将字体族设置为 Segoe UI Symbol 或其他包含 U+1F50D 左指向放大镜图标的字体,该字体必须可以在目标系统中找到。

结果演示


11

这里有一种只使用样式表就能实现的方法:

QLineEdit {
    background: #f3f3f3;
    background-image: url(:Images/search.svg); /* actual size, e.g. 16x16 */
    background-repeat: no-repeat;
    background-position: left;
    color: #252424;
    font-family: SegoeUI;
    font-size: 12px;
    padding: 2 2 2 20; /* left padding (last number) must be more than the icon's width */
}

这是结果:

一个QLineEdit搜索框

它仍然不完美。您无法对图标的位置有太多的控制。


2
以下是一个对图标位置有影响的示例: QLineEdit { background-color: white; padding-right: 8px; padding-left: 16px; background-image: url("%s"); background-repeat: no-repeat; background-position: right; background-origin: content; } QLineEdit:disabled { /* 使用不同的背景色实现相同效果 */}使用内容区域作为背景图片的起始位置可以确保填充(padding)应用到图片上。 - PiRK
1
@PiRK,我尝试了你的示例,但它并没有产生期望的结果(Qt 5.12)。它被对齐到右侧,如果我将其更改为左侧,则图标和文本会重叠绘制。我已经尝试了很长时间通过样式表和代理样式来修改Qt,以使这些图标和文本在QLineEdit、QComboBox和可编辑的QComboBox(带有QLineEdit)中以相同的方式绘制。你能否重新访问并发布一个有效的示例。谢谢 :) - bleze
在我的例子中,搜索图标应该在右侧。我的行编辑器总是足够长,搜索字符串也足够短,以至于用户不会注意到图标和文本的重叠。很抱歉我不能提供更多帮助。 - PiRK

10
为了达到这样的结果:
Qt icon QLineEdit 你可以继承QLineEdit。
因此你的头文件应该像这样:
#ifndef LINEEDITICON_H
#define LINEEDITICON_H

#include <QLineEdit>
#include <QIcon>

class LineEditIcon : public QLineEdit
{
    Q_OBJECT

public:
    LineEditIcon(const QIcon icon, QWidget *parent = Q_NULLPTR);
    ~LineEditIcon();
    void setIcon(QIcon icon);    
protected:
    virtual void paintEvent(QPaintEvent *event);    
private:
    QIcon m_icon;       
};

#endif // LINEEDITICON_H

你的源文件看起来像这样:

#include "lineediticon.h"
#include <QPainter>

LineEditIcon::LineEditIcon(const QIcon icon, QWidget *parent)
    : QLineEdit(parent)
{
    setIcon(icon);
}

LineEditIcon::~LineEditIcon()
{    
}

void LineEditIcon::setIcon(QIcon icon)
{
    m_icon = icon;
    if (m_icon.isNull())
        setTextMargins(1, 1, 1, 1);
    else
        setTextMargins(20, 1, 1, 1);
}

void LineEditIcon::paintEvent(QPaintEvent * event)
{
    QLineEdit::paintEvent(event);
    if (!m_icon.isNull()) {
        QPainter painter(this);
        QPixmap pxm = m_icon.pixmap(height() - 6, height() - 6);
        int x = 2, cx = pxm.width();

        painter.drawPixmap(x, 3, pxm);
        painter.setPen(QColor("lightgrey"));
        painter.drawLine(cx + 2, 3, cx + 2, height() - 4);
    }
}

编辑:一个可能的解决方案是使用自定义插件,以便在QtDesigner中直接使用它。


8

QT5 addAction

```

const QIcon passwordIcon(":/new/icons/res/passwd.png");
ui->password->setClearButtonEnabled(true);
ui->password->addAction(passwordIcon, QLineEdit::LeadingPosition);

```


2

从QT 5.2版本开始,您可以像这样操作。如果要使其更加灵活,请使用指针:


QIcon *ico;
ico = new QIcon(":/images/search.ico");
searchEdit->addAction(*ico, QLineEdit::LeadingPosition);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接