【问题标题】:ComboBox with Checkboxes inside, C++ Qt, select/unselect all checkboxes内部带有复选框的组合框,C++ Qt,选择/取消选择所有复选框
【发布时间】:2013-09-30 04:11:30
【问题描述】:

我编写了一个简单的组合框,其中包含复选框作为项目。当我选择一个项目并按下按钮时,它会显示我选择的项目。但我想做这样的事情:我有一个名为“all”的项目 - 当我选择它时,应该选择所有其他项目,当我取消选择它时,应该取消选择所有其他项目。有什么想法吗?

ma​​inwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>
#include <QComboBox>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    Ui::MainWindow *ui;
    QStandardItemModel *model;

private slots:

    void buttonclicked();
};

#endif // MAINWINDOW_H

ma​​inwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->model = new QStandardItemModel(4, 1); // 4 rows, 1 col
    for (int r = 0; r < 4; ++r)
    {
        QStandardItem* item;
        if(r == 0)
            item = new QStandardItem(QString("All"));
        else
            item = new QStandardItem(QString("Item %0").arg(r));

        item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
        item->setData(Qt::Unchecked, Qt::CheckStateRole);

        model->setItem(r, 0, item);
    }

    ui->comboBox->setModel(model);

    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(buttonclicked()));
}

void MainWindow::buttonclicked()
{
    unsigned int i;
    for(i=0; i<ui->comboBox->count(); i++)
    {
        QModelIndex index = ui->comboBox->model()->index(i, 0);
        QVariant v = index.data(Qt::CheckStateRole);
        int j = v.toInt();
        if(j == 2)
        {
            QModelIndex ii = ui->comboBox->model()->index(i, 0);
            QString text = ii.data(Qt::DisplayRole).toString();
            qDebug() << text;
        }

    }
    qDebug()<<"";
}

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

ma​​in.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

ui 文件

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QComboBox" name="comboBox">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>50</y>
      <width>201</width>
      <height>23</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>110</x>
      <y>100</y>
      <width>181</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>Check what was selected</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>20</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

看起来像这样:

【问题讨论】:

    标签: c++ qt checkbox combobox


    【解决方案1】:

    为此按钮实现qtslot,这样当单击/触发它时,您将遍历所需组合框中的所有复选框并编辑它们的选中状态。

    【讨论】:

    • 用于按钮,而不用于复选框?
    • 正确。动作是当单击“全部”按钮时,您所做的将是组合框的内容。
    • 哦,你不是指一个按钮,你的意思是在组合框中有一个名为“all”的文字项目?我会让您的生活更轻松,并在组合框上方有一个按钮,如果切换该按钮将选择所有或取消选择框中的所有项目。容易得多,并且不必教组合框中的所有项目如何管理其他项目,他通常不必知道
    • 是的,我的意思是组合框中名为“All”的项目——当用户选择这个时,所有其他的也应该被选中(取消选择也是如此)
    • @BrianBrown 另一种选择是将组合框子类化并拥有组合框类本身并将“全部”元素放在那里,这样您就可以为其提供自定义实现,而无需向第 3 方类教授模型的内部结构。 (但是当您要求他选择所有其他项目时,您是否选择了所有项目?等等)
    【解决方案2】:

    在尝试使用您的代码复制复选框列表时,我一直在学习如何使用模型子类化,并找到了一种在填充列表更改的任何复选框中检查状态时触发信号的方法。

    在 MainWindow.h 中声明一个公共槽:

    public slots:
            void itemCheck(QModelIndex a, QModelIndex b);
    

    在 MainWindow.cpp 中实现 slot:

    void MainWindow::void itemCheck(QModelIndex a, QModelIndex b)
    {
        qDebug() << "check event";
    }
    

    并将这个新插槽连接到 模型的 dataChanged 信号:

    connect(ui->comboBox->model(), SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector<int>)), this, SLOT(itemCheck(QModelIndex, QModelIndex)));
    

    我认为,可以过滤“全部”复选框的事件并适当设置其他复选框。 设法让它工作:

    void MainWindow::itemCheck(QModelIndex a, QModelIndex b)
    {
        qint16 i;
        QModelIndex cycleIndex;
        // if "All" checked
        if (a.row() == 0)
        {
            // blocking new dataChanged singnal while managing other checkboxes
            ui->comboBox->model()->blockSignals(true);
            // setting other checkboxes appropriately
            if (a.data(Qt::CheckStateRole).toBool())
            {
                for (i = 1; i<ui->comboBox->count(); i++)
                {
                    cycleIndex = ui->comboBox->model()->index(i, 0);
                    ui->comboBox->model()->setData(cycleIndex, Qt::Checked, Qt::CheckStateRole);
                }
            } else
            {
                for (i = 1; i<ui->comboBox->count(); i++)
                {
                    cycleIndex = ui->comboBox->model()->index(i, 0);
                    ui->comboBox->model()->setData(cycleIndex, Qt::Unchecked, Qt::CheckStateRole);
                }
            }
            ui->comboBox->model()->blockSignals(false);
        }
    }
    

    希望这将有助于从零开始学习 Qt 的人。

    【讨论】:

      猜你喜欢
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2011-10-09
      • 2021-03-22
      • 2023-04-02
      • 1970-01-01
      相关资源
      最近更新 更多