Qt之QComboBox的可删除item

QComboBox的能够在setEditable模式下,只能增加而不能删除,注定了用户体研极差的,而且在输入有误时也没有任何办法,所以自定义comboBox

参考:Qt之QComboBox(基本应用、代理设置)_一去二三里_新浪博客

参考:QComboBox下拉框给选项增加删除按钮_龚建波-CSDN博客

直接上代码

头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QLabel>
#include <QComboBox>
#include <QListWidget>
#include <QPushButton>
#include <QMainWindow>
#include <QMouseEvent>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QListWidgetItem>

namespace Ui {
class MainWindow;
}
class MyComboBox;

class ComboBoxItem : public QWidget
{
    Q_OBJECT
public:
    explicit ComboBoxItem(QWidget *parent = nullptr);
    void setLabelText(QString text);
    QString getLabelText();
signals:
    void SignalDeleteClicked(const QString &text);
    void SignalDeleteProperty(const QString &text);
    void SignalShowClicked(const QString &text);
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
private:
    bool mouse_press;
    QPushButton *btn;
    QLabel *label;
};

class MyComboBox : public QComboBox
{
    Q_OBJECT
public:
    explicit MyComboBox(QWidget *parent = nullptr);
    void MyAddItem(const QString &text);
public slots:
    void SlotRemoveItem(const QString text);
    void SlotRemoveProperty(const QString PropertyStr);
    void SlotShowItem(const QString text);
protected:
    void keyReleaseEvent(QKeyEvent  *event);
private:
    QListWidget *listWidget;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    MyComboBox *comboBox;
};

#endif // MAINWINDOW_H

源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    comboBox = new MyComboBox(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

/* ComboBoxItem初始化 */
ComboBoxItem::ComboBoxItem(QWidget *parent):
    QWidget(parent)
{
    mouse_press = false;
    QFont font;
    font.setPixelSize(11);
    btn = new QPushButton;
    label = new QLabel;
    btn->setFont(font);
    label->setFont(font);
    QPixmap pixmap("D:\\Data\\anyu\\AfterSaleServer\\Client\\AGS_AfterSale_Client\\ClearIco.png");
    btn->setIcon(pixmap);
    btn->setIconSize(pixmap.size());
    btn->setStyleSheet("background:transparent;");
    connect(btn,&QPushButton::clicked,[this]{
        emit SignalDeleteClicked(label->text());
        emit SignalDeleteProperty(property("count").toString());
    });
    QHBoxLayout *layout=new QHBoxLayout;
    layout->addWidget(label);
    layout->addStretch();
    layout->addWidget(btn);
    layout->setContentsMargins(5, 5, 5, 5);
    layout->setSpacing(5);
    this->setLayout(layout);
}
/* 设置combobox当前显示文本 */
void ComboBoxItem::setLabelText(QString text)
{
    label->setText(text);
}

/* 获取combobox当前显示文本 */
QString ComboBoxItem::getLabelText()
{
    return label->text();
}

/* 用于combobox显示当前点击的文本 */
void ComboBoxItem::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton){
        mouse_press = true;
    }
}
/* 用于combobox显示当前点击的文本 */
void ComboBoxItem::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    if(mouse_press){
        emit SignalShowClicked(label->text());
        mouse_press = false;
    }
}
/* 初始化 */
MyComboBox::MyComboBox(QWidget *parent): QComboBox(parent)
{
    setStyleSheet("QComboBox QAbstractItemView::item {height : 30px ;}");
    listWidget = new QListWidget();
//    resize(200,50);
    setModel(listWidget->model());
    setView(listWidget);
    clear();
    setEditable(true); //设置QComboBox可编辑
    for(int i=0; i<3; i++){
        MyAddItem("设置QComboBox可编辑"+QString::number(i));
    }
}
/* 自定义的添加item */
void MyComboBox::MyAddItem(const QString &text)
{
    static int count = 0;
    static int TextMaxLen = 0;
    if(fontMetrics().width(text) > TextMaxLen){
        TextMaxLen = fontMetrics().width(text);
    }
    resize(TextMaxLen+100,50);
    ComboBoxItem *item = new ComboBoxItem();
    item->setLabelText(text);
//    connect(item,&ComboBoxItem::SignalDeleteClicked,this,&MyComboBox::SlotRemoveItem);
    connect(item,&ComboBoxItem::SignalDeleteProperty,this,&MyComboBox::SlotRemoveProperty);
    connect(item,&ComboBoxItem::SignalShowClicked,this,&MyComboBox::SlotShowItem);
    QListWidgetItem *list_item = new QListWidgetItem(listWidget);
    item->setProperty("count",QString::number(count++));
    listWidget->setItemWidget(list_item, item);
    qDebug() << item->size() << listWidget->itemWidget(list_item)->geometry();
}
/* 删除选择的文本,注意此处删除的是listwidget而不是combobox,combobox是一个空的内容 */
void MyComboBox::SlotRemoveItem(const QString text)
{
    qDebug() << "SlotRemoveItem/text = " << text;
    int list_count = listWidget->count();
    for(int i=0; i < list_count;i++){
        QListWidgetItem *item = listWidget->item(i);
        ComboBoxItem *clickitem = static_cast<ComboBoxItem *>(listWidget->itemWidget(item));
        QString LabelText = clickitem->getLabelText();
        if(text == LabelText) {
            listWidget->takeItem(i);
            delete item;
            break;
        }
    }
}

/* 删除选择的属性对应的item,因为文本可能重复,但是设置的属性是唯一的,注意此处删除的是listwidget而不是combobox,combobox是一个空的内容 */
void MyComboBox::SlotRemoveProperty(const QString PropertyStr)
{
    qDebug() << "SlotRemoveProperty/text = " << PropertyStr;
    int list_count = listWidget->count();
    for(int i=0; i < list_count;i++){
        QListWidgetItem *item = listWidget->item(i);
        ComboBoxItem *clickitem = static_cast<ComboBoxItem *>(listWidget->itemWidget(item));
        QString LabelText = clickitem->property("count").toString();
        if(PropertyStr == LabelText) {
            listWidget->takeItem(i);
            delete item;
            break;
        }
    }
}
/* 设置当前combobox的显示文本 */
void MyComboBox::SlotShowItem(const QString text)
{
    qDebug() << "ShowItem/text = " << text;
    setCurrentText(text);
    hidePopup();
}
/* 判断combobox是否enter,是的话需要将自动创建的combobox的item删除掉,再自己主动创建 */
void MyComboBox::keyReleaseEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Enter|| event->key() == Qt::Key_Return){
        QString text = currentText();
        removeItem(count()-1);
        MyAddItem(text);
        setCurrentText(text);
//        qDebug() << count() << listWidget->count();
//        for(int i = 0;i < count();i++){
//            qDebug() << itemText(i) << ((ComboBoxItem *)listWidget->itemWidget(listWidget->item(i)))->getLabelText();
//        }
    }
}

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中,可以通过自定义一个QComboBoxItemDelegate来实现在QComboBox中添加一个Button,并且点击这个Button实现关闭当前选中的item。具体步骤如下: 1. 新建一个类,继承自QStyledItemDelegate,重写createEditor、updateEditorGeometry和paint方法。其中,createEditor方法用于创建一个QWidget对象作为ItemDelegate的编辑器,updateEditorGeometry方法用于更新编辑器的位置和大小,paint方法用于绘制ItemDelegate的内容。 2. 在createEditor方法中创建一个QPushButton对象,并且将其与QComboBox的currentIndexChanged信号连接起来。在这个槽函数中,可以通过QComboBox的currentIndex方法获取当前选中的item的索引,然后通过QComboBox的removeItem方法将其从QComboBox删除。 3. 将自定义的ItemDelegate对象设置为QComboBoxItemDelegate,即可在QComboBox中添加一个Button。 下面是示例代码: ``` class ComboBoxDelegate : public QStyledItemDelegate { public: QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override { QPushButton *button = new QPushButton("Close", parent); connect(button, &QPushButton::clicked, this, [=](){ QComboBox *comboBox = qobject_cast<QComboBox*>(parent); if(comboBox) { int currentIndex = comboBox->currentIndex(); comboBox->removeItem(currentIndex); } }); return button; } void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override { editor->setGeometry(option.rect); } void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { painter->drawText(option.rect, index.data().toString()); } }; //在使用QComboBox的地方设置ItemDelegate QComboBox *comboBox = new QComboBox(this); comboBox->setItemDelegate(new ComboBoxDelegate()); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值