美文网首页
QCheckBox和QComboBox

QCheckBox和QComboBox

作者: downdemo | 来源:发表于2018-10-25 10:46 被阅读49次

QComboBox
QCheckBox

QComboBox

  • 新建
QComboBox* comboBox = new QComboBox;
comboBox->addItem("op0");
comboBox->addItem("op1");
comboBox->addItem("op2");
comboBox->addItem("op3");

QCheckBox* checkBox = new QCheckBox("isOK");
  • 添加到QTableWidget
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); // 单击编辑
  • QComboBox常用成员函数
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);
  • QComboBox信号槽
// 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

  • 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)
  • QCheckBox信号槽
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);
}

相关文章

网友评论

      本文标题:QCheckBox和QComboBox

      本文链接:https://www.haomeiwen.com/subject/jslqtqtx.html