2013-09-24 9 views
5

Napisałem prosty combobox z checkboxami jako jego przedmiotami. Po wybraniu elementu i naciśnięciu przycisku pokazuje on wybrany element. Ale chciałbym zrobić coś takiego: mam element o nazwie "all" - kiedy go wybiorę, wszystkie pozostałe elementy powinny zostać wybrane, a gdy je odznaczę, wszystkie pozostałe elementy powinny zostać usunięte. Jakieś pomysły?ComboBox z Checkboxes inside, C++ Qt, zaznacz/odznacz wszystkie pola wyboru

mainwindow.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 

mainwindow.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; 
} 

main.cpp

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

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

    return a.exec(); 
} 

ui plik

<?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> 

Wygląda to tak:

enter image description here

Odpowiedz

1

Wdrożenie qtslot tego przycisku tak, że gdy zostanie kliknięty/wyzwalany będzie iteracyjne nad wszystkie pola wyboru w pożądanym combobox i edytuj ich sprawdzony stan.

+0

dla przycisku, a nie dla pola wyboru? –

+0

Prawidłowo. Akcja następuje po kliknięciu przycisku "wszystko", co zrobisz z zawartością combobox. – UpAndAdam

+0

oh nie masz na myśli przycisku, masz na myśli posiadanie dosłownej rzeczy w comboboxie o nazwie "all"? Ułatwiłbym ci życie i posiadałbym przycisk nad comboboxem, który gdybyś nacisnął albo zaznaczyłby wszystko, albo odznaczyłby wszystkie elementy w pudełku.O wiele łatwiej i nie trzeba uczyć wszystkich elementów w comboboxie jak zarządzać innymi przedmiotami, które generalnie nie powinien wiedzieć o – UpAndAdam

0

Nauczyłem się, jak korzystać z podklasy modelu podczas próby replikowania listy checkbox za pomocą kodu i znalazłem sposób, aby wyzwolić sygnał, gdy stan sprawdzenia w którymkolwiek z pól zapełniających listę zmienia się.

Deklarowanie gniazdo publicznego w MainWindow.h:

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

Realizacja szczelinę w MainWindow.cpp:

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

i podłączeniu nowego gniazdo do dataChanged sygnału modelu:

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

Cienki k, możliwe jest filtrowanie zdarzenia dla pola wyboru "Wszystkie" i odpowiednie ustawienie pozostałych. udało się uzyskać to działa:

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); 
    } 
} 

nadzieję, że pomoże komuś nauki Qt od zera.