【Qt一骚操作】多选下拉框multicombox 的研究

针对multicombox 的研究

前言

由于Qt仅仅提供多选下拉框只能选择单项项目,要实现多选项选择,因此需要自己设计和编码,针对multicombox 的研究如下,总结网上及自己实际经验,汇总如下:

(1)下拉listview设置

左边为样式A为“fusion”样式,在ubuntu下的样式似乎就是这个,它的特点是下拉列表会把文字框和箭头盖住。右边样式B为“windowsvista”样式,它是win10下Qt的默认样式,其特点是下拉列表会显示在文字框和箭头下方,所以不会盖住文字框和箭头。 那么如何在不改变全局样式(即指定“fusion”样式或“windowsvista”样式)的情况下对QComboBox的样式进行控制,使其显示为样式A或样式B呢?如果全局样式使得QComboBox为样式A,而你想使用样式B,这种情况是比较简单的,使用qss即可满足需求,对QComboBox调用setStyleSheet(“QComboBox {combobox-popup: 0;}”)后,样式就变成了这样: 样式C

this->setStyleSheet("QComboBox {combobox-popup: 0;}");

(2)设置编辑框、下拉界面、数据模型

//为 ComBox 设置编辑框
m_pLineEdit = new QLineEdit(this);
m_pLineEdit->setReadOnly(true);
this->setLineEdit(m_pLineEdit);

//设置 ComBox 下拉界面
m_pListView = new QListView(this);
m_pListView->installEventFilter(this);
this->setView(m_pListView);

//设置 ComBox 数据模型
m_pItemModel = new QStandardItemModel(this);
this->setModel(m_pItemModel);

(3)连接信号,当点击多选的某一项进行记录保存

connect(m_pListView, &QListView::pressed, this, &MultiComBox::sltActivated);

(4)添加下拉菜单内容

//*************************************************
//Function: AddItems
//Description: 添加下拉菜单内容
//Input: menus:菜单内容列表
//Return: 若中途执行失败,则返回false,中断操作;否则,返回真,继续后续操作
//*************************************************
void MultiComBox::addItems(QList<MenuItem *> menus)
{
QStandardItem *pNewItem;
foreach (MenuItem *pMenuItem, menus) {
if (pMenuItem == nullptr) {
// 释放内存
delete pMenuItem;
pMenuItem = nullptr;
continue;
}
pNewItem = new QStandardItem(pMenuItem->GetMenuName());
pNewItem->setCheckState(pMenuItem->GetIsChecked() ? Qt::Checked : Qt::Unchecked);
pNewItem->setData(pMenuItem->GetMenuId());
m_pItemModel->appendRow(pNewItem);

    // 释放内存
    delete pMenuItem;
    pMenuItem = nullptr;
}

}
(5)获取多选内容、index

QStringList MultiComBox::getItemsText()
{
QStringList strs;
QString str = m_pLineEdit->text();
if (!str.isEmpty()) {
strs = str.split(";");
}
return strs;
}

QList MultiComBox::getItemsId()
{
QList ids;
for (int i = 0; i < m_pItemModel->rowCount(); i++) {
QStandardItem *item = m_pItemModel->item(i);
if (item->checkState() == Qt::Checked) {
ids << item->data().toInt();
}
}
return ids;
}
(6)重点:根据鼠标相应位置,判断是否隐藏下拉框,并且在这里发送记录日志的信号

//*************************************************
//Function: hidePopup
//Description: 根据鼠标相应位置,判断是否隐藏下拉菜单
//*************************************************
void MultiComBox::hidePopup()
{
int width = this->view()->width();
int height = this->view()->height();
int x = QCursor::pos().x() - mapToGlobal(geometry().topLeft()).x() + geometry().x();
int y = QCursor::pos().y() - mapToGlobal(geometry().topLeft()).y() + geometry().y();

QRect rectView(0, this->height(), width, height);
if (!rectView.contains(x, y) && this->view()->isVisible()) {
    QComboBox::hidePopup();
    updateText();

    // 发送全部已选选项的index  用于日志
    QList<int> listIndex;
    for (int i = 0; i < m_pItemModel->rowCount(); i++) {
        QStandardItem *item = m_pItemModel->item(i);
        if (item->checkState() == Qt::Checked) {
            listIndex.append(i);
        }
    }
    Q_EMIT sendSelected(listIndex);
}

}
(7)更新文本

//*************************************************
//Function: UpdateText
//Description: 更新lineedit文本
//*************************************************
void MultiComBox::updateText()
{
QStringList strs;
for (int i = 0; i < m_pItemModel->rowCount(); i++) {
QStandardItem *item = m_pItemModel->item(i);
if (item->checkState() == Qt::Checked) {
strs << item->text();
}
}
m_pLineEdit->setText(strs.join(";"));
m_pLineEdit->setToolTip(strs.join("\n"));
}

void MultiComBox::sltActivated(const QModelIndex &index)
{
QStandardItem *item = m_pItemModel->item(index.row());
Qt::CheckState checkState = item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked;
item->setCheckState(checkState);

void MultiComBox::sltActivated(const QModelIndex &index)
{
QStandardItem *item = m_pItemModel->item(index.row());
Qt::CheckState checkState = item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked;
item->setCheckState(checkState);
}

void MultiComBox::setActivated(int row)
{
QStandardItem *item = m_pItemModel->item(row);
Qt::CheckState checkState = Qt::Checked;
item->setCheckState(checkState);

// 每次初始化显示全部日期
updateText();

}

QString MultiComBox::getSelectedRows()
{
QStringList strs;
for (int i = 0; i < m_pItemModel->rowCount(); i++) {
QStandardItem *item = m_pItemModel->item(i);
if (item->checkState() == Qt::Checked) {
strs << QString::number(i);
}
}

return strs.join(";");

}

QString MultiComBox::getSelectedIndexs()
{
QStringList strs;
for (int i = 0; i < m_pItemModel->rowCount(); i++) {
QStandardItem *item = m_pItemModel->item(i);
if (item->checkState() == Qt::Checked) {
strs << QString::number(i);
} else if (item->checkState() == Qt::Unchecked) {
strs.removeOne(QString::number(i));
}
}
return strs.join(";");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monster_H777

我直说吧:你的奖励我的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值