QComboBox
QCheckBox
QComboBox
QComboBox* comboBox = new QComboBox;
comboBox->addItem("op0");
comboBox->addItem("op1");
comboBox->addItem("op2");
comboBox->addItem("op3");
QCheckBox* checkBox = new QCheckBox("isOK");
table = new QTableWidget(3, 3, nullptr);
table->horizontalHeader()->setVisible(false);
table->setCellWidget(0, 0, comboBox);
table->setCellWidget(1, 0, checkBox);
- 未解决bug:QComboBox添加到表格中后,选中但不双击编辑框的单元格,直接输入拼音将导致程序崩溃,错误信息为栈溢出
// 出现问题的位置为return a.exec();
0x00007FF9515DFB69 (Qt5Cored.dll)处(位于 QtGuiApplication1.exe 中)引发的异常: 0xC00000FD: Stack overflow (参数: 0x0000000000000001, 0x000000CE36CB3FE8)。
0x00007FF9515DFB69 (Qt5Cored.dll) (QtGuiApplication1.exe 中)处有未经处理的异常: 0xC00000FD: Stack overflow (参数: 0x0000000000000001, 0x000000CE36CB3FE8)。
- 绕过此问题的方法是,将QTableWidget设置为单击单元格进入编辑状态
table->setEditTriggers(QAbstractItemView::CurrentChanged); // 单击编辑
int count() const;
int currentIndex() const;
QString currentText() const;
QString itemText(int index) const;
void insertItem(int index, const QString &text, const QVariant &userData = QVariant());
void insertSeparator(int index); // 在index位置前插入一条分割线
void removeItem(int index);
void setEditable(bool editable);
void setMaxCount(int max);
// currentIndexChanged有int和QString参数两个重载版本,必须指定版本
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &dlg::slot);
// 旧的语法
connect(comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot()));
// 也可以用currentTextChanged,它没有重载版本,但也会在改变选项时发送
connect(comboBox, &QComboBox::currentTextChanged, this, &dlg::slot);
void dlg::slot()
{
if (comboBox->currentIndex() == 0)
{
table->setRowHidden(1, true);
table->setRowHidden(2, true);
}
else if (comboBox->currentIndex() == 1)
{
table->setRowHidden(1, false);
table->setRowHidden(2, true);
}
else if (comboBox->currentIndex() == 2)
{
table->setRowHidden(1, true);
table->setRowHidden(2, false);
}
else
{
table->setRowHidden(0, false);
table->setRowHidden(1, false);
table->setRowHidden(2, false);
}
}
QCheckBox
bool isChecked() const; // 返回两态中的一个状态
void setChecked(bool isChecked); // 设置两态中的一个状态
void setTristate(bool y = true); // 设置开启三态模式
Qt::CheckState checkState() const; // 返回三态中的一个状态
void setCheckState(Qt::CheckState state); // 设置三态中的一个状态
Qt::CheckState包含
Qt::Unlocked,即Qt::CheckState(0)
Qt::PartiallyChecked,即Qt::CheckState(1)
Qt::Checked,即Qt::CheckState(2)
connect(checkBok, &QCheckBox::stateChanged, this, &dlg::slot);
将QComboBox下拉选项设置为QCheckBox
效果图
#pragma once
#include <qwidget.h>
#include "ui_MyComboBox.h"
#include "qboxlayout.h"
#include "qcombobox.h"
#include "qcheckbox.h"
#include "qlineedit.h"
#include "qlistwidget.h"
namespace Ui
{
class MyComboBox;
}
class MyComboBox : public QWidget
{
Q_OBJECT
public:
explicit MyComboBox(QWidget* parent = Q_NULLPTR);
~MyComboBox();
private slots:
void checkBoxSlots(int state);
void lineEditSlots(const QString &text);
private:
Ui::MyComboBox* ui;
QComboBox* comboBox;
QListWidget* listWidget;
QLineEdit* lineEdit;
private:
QString lineEditText;
};
#include "MyComboBox.h"
MyComboBox::MyComboBox(QWidget* parent) : QWidget(parent), ui(new Ui::MyComboBox)
{
ui->setupUi(this);
listWidget = new QListWidget;
QVector<QString> v{ tr(u8"选项1"), tr(u8"选项2"), tr(u8"选项3") };
for (int i = 0; i < v.size(); ++i)
{
QListWidgetItem* item = new QListWidgetItem(listWidget);
item->setData(Qt::UserRole, i);
listWidget->addItem(item);
listWidget->addItem(item);
QCheckBox *checkBox = new QCheckBox;
checkBox->setText(v[i]);
listWidget->setItemWidget(item, checkBox);
connect(checkBox, &QCheckBox::stateChanged, this, &MyComboBox::checkBoxSlots);
}
lineEdit = new QLineEdit;
lineEdit->setReadOnly(true);
comboBox = new QComboBox;
comboBox->setModel(listWidget->model());
comboBox->setView(listWidget); // setView之前必须先setModel
comboBox->setLineEdit(lineEdit);
connect(lineEdit, &QLineEdit::textChanged, this, &MyComboBox::lineEditSlots);
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(comboBox);
setLayout(layout);
}
MyComboBox::~MyComboBox()
{
delete ui;
}
void MyComboBox::checkBoxSlots(int state)
{
QString strToShow;
for (int i = 0; i < listWidget->count(); ++i)
{
QListWidgetItem* item = listWidget->item(i);
QCheckBox* checkBox = qobject_cast<QCheckBox*>(listWidget->itemWidget(item));
if (checkBox->isChecked())
{
strToShow.append(tr(u8"、")).append(checkBox->text());
}
}
lineEditText.clear();
if (!strToShow.isEmpty())
{
strToShow.remove(0, 1); // 移除开头的符号
lineEditText = strToShow;
}
lineEdit->setText(lineEditText);
}
void MyComboBox::lineEditSlots(const QString& text)
{
lineEdit->setText(lineEditText);
}
添加自定义QComboBox到QTableWidget
- 将此自定义控件用setCellWidget添加到QTableWidget会出现不能填满单元格的问题
- 将MyCBX内部的layout设置边距之后可以改善,但仍然不能填满单元格
layout->setContentsMargins(0, 0, 0, 0);
layout设置边距之后
comboBox = new QComboBox(this);
comboBox->setGeometry(0, 0, 200, 30);
不使用layout
#pragma once
#include <qwidget.h>
#include "ui_MyComboBox.h"
#include "qcombobox.h"
#include "qcheckbox.h"
#include "qlineedit.h"
#include "qlistwidget.h"
namespace Ui
{
class MyComboBox;
}
class MyComboBox : public QWidget
{
Q_OBJECT
public:
explicit MyComboBox(const QVector<QString>& option,
int width, int height, QWidget* parent = Q_NULLPTR);
~MyComboBox();
private slots:
void checkBoxSlots(int state);
void lineEditSlots(const QString &text);
private:
Ui::MyComboBox* ui;
QListWidget* listWidget;
QLineEdit* lineEdit;
QComboBox* comboBox;
private:
QString lineEditText;
};
#include "MyComboBox.h"
MyComboBox::MyComboBox(const QVector<QString>& option,
int width, int height, QWidget* parent)
: QWidget(parent), ui(new Ui::MyComboBox)
{
ui->setupUi(this);
listWidget = new QListWidget;
for (int i = 0; i < option.size(); ++i)
{
QListWidgetItem* item = new QListWidgetItem(listWidget);
item->setData(Qt::UserRole, i);
listWidget->addItem(item);
listWidget->addItem(item);
QCheckBox *checkBox = new QCheckBox;
checkBox->setText(option[i]);
listWidget->setItemWidget(item, checkBox);
connect(checkBox, &QCheckBox::stateChanged, this, &MyComboBox::checkBoxSlots);
}
lineEdit = new QLineEdit;
lineEdit->setReadOnly(true);
comboBox = new QComboBox(this);
comboBox->setGeometry(0, 0, width, height);
comboBox->setModel(listWidget->model());
comboBox->setView(listWidget); // setView之前必须先setModel
comboBox->setLineEdit(lineEdit);
connect(lineEdit, &QLineEdit::textChanged, this, &MyComboBox::lineEditSlots);
}
MyComboBox::~MyComboBox()
{
delete ui;
}
void MyComboBox::checkBoxSlots(int state)
{
QString strToShow;
for (int i = 0; i < listWidget->count(); ++i)
{
QListWidgetItem* item = listWidget->item(i);
QCheckBox* checkBox = qobject_cast<QCheckBox*>(listWidget->itemWidget(item));
if (checkBox->isChecked())
{
strToShow.append(tr(u8"、")).append(checkBox->text());
}
}
lineEditText.clear();
if (!strToShow.isEmpty())
{
strToShow.remove(0, 1);
lineEditText = strToShow;
}
lineEdit->setText(lineEditText);
}
void MyComboBox::lineEditSlots(const QString& text)
{
lineEdit->setText(lineEditText);
}
网友评论