2013-05-21 35 views
9

Tôi đã làm theo hướng dẫn Phân phối hộp quay, mà Qt cung cấp, để cố gắng triển khai QItemDelegate của riêng tôi. Nó sẽ được sử dụng để chỉ định một QComboBox để biểu diễn dữ liệu trong một tế bào QTableView nhưng nó không hoạt động.Qt Sử dụng QItemDelegate tùy chỉnh cho QTableView

enter image description here

Vấn đề lớn nhất của tôi là tôi không biết khi nào QItemDelegate của tôi sẽ được sử dụng.

  • khi itemModel-> setData được sử dụng hoặc khi itemModel-> setItem. Tôi sẽ nghi ngờ setItem vì tôi reimplemented một QItemDelegate (nhấn mạnh vào "Item") nhưng hướng dẫn sử dụng setData và nó hoạt động tốt.

  • Tôi biết rằng nếu QItemDelegate được chỉ định không hoạt động, nó sử dụng giá trị mặc định nhưng làm cách nào để bây giờ mà tôi đã chỉ định không hoạt động?

  • khi nào tôi nên nghi ngờ QTableView sử dụng đại biểu của mình. Tôi muốn chỉ định đại biểu nào sẽ sử dụng cho từng ô. Điều này có khả thi hay không QTableView chỉ sử dụng một đại biểu trong suốt?

  • Làm cách nào để chỉ định các mục để điền QComboBox khi nó được hiển thị bởi QTableView?

tôi thực hiện QItemDelegate đây:

  • phần mà tôi cố gắng thêm các tế bào đó là giả sử dụng QComboBox là theo nhận xét "Enabled" trong mainwindow.cpp tiếp tục xuống bài này.

qcomboboxitemdelegate.h

#ifndef QCOMBOBOXITEMDELEGATE_H 
#define QCOMBOBOXITEMDELEGATE_H 

#include <QItemDelegate> 
#include <QComboBox> 

class QComboBoxItemDelegate : public QItemDelegate 
{ 
Q_OBJECT 

public: 

explicit QComboBoxItemDelegate(QObject *parent = 0); 

QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index); 
void setEditorData(QWidget *editor, const QModelIndex &index); 
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index); 
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,  const QModelIndex &index); 

signals: 

private: 

}; 

#endif // QCOMBOBOXITEMDELEGATE_H 

qcomboboxitemdelegate.cpp

#include "qcomboboxitemdelegate.h" 
#include <QDebug> 

QComboBoxItemDelegate::QComboBoxItemDelegate(QObject *parent) 
: QItemDelegate(parent) 
{ 

} 

QWidget* QComboBoxItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) { 
// create widget for use 
QComboBox* comboBox = new QComboBox(parent); 
return comboBox; 
} 

void QComboBoxItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) { 
// update model widget 
QString value = index.model()->data(index, Qt::EditRole).toString(); 
qDebug() << "Value:" << value; 
QComboBox* comboBox = static_cast<QComboBox*>(editor); 
comboBox->setCurrentIndex(comboBox->findText(value)); 
} 

void QComboBoxItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) { 
// store edited model data to model 
QComboBox* comboBox = static_cast<QComboBox*>(editor); 
QString value = comboBox->currentText(); 
model->setData(index, value, Qt::EditRole); 
} 

void QComboBoxItemDelegate::updateEditorGeometry(QWidget *editor, const  QStyleOptionViewItem &option, const QModelIndex &index) { 
editor->setGeometry(option.rect); 
} 

mainwindow.cpp: đây là nơi tôi khởi tạo QStandardItemModel

void MainWindow::init() { 
itemModel = new QStandardItemModel(this); 
} 

void MainWindow::setupUi() { 
this->setWindowTitle("QAlarmClock");   
QStringList labelList; 
labelList << "Alarm Name" << "Time" << "Enabled"; 
itemModel->setHorizontalHeaderLabels(labelList);  
ui->tableView->setModel(itemModel); 
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); 
ui->tableView->setItemDelegate(comboBoxItemDelegate); 
} 

void MainWindow::on_actionNew_triggered() { 
alarmDialog = new AlarmDialog(this); 
connect(alarmDialog, SIGNAL(on_close()), this, SLOT(on_alarmDialog_close())); 
alarmDialog->exec(); 
} 

mainwindow.cpp: đây là nơi tôi cập nhật QStandardItemModel

void MainWindow::on_alarmDialog_close() { 
QString alarmName = alarmDialog->getAlarmName(); 
QDateTime alarmDateTime = alarmDialog->getDateTime(); 

itemModel->insertRow(itemModel->rowCount()); 
int rowCount = itemModel->rowCount(); 

// Alarm Name 
QStandardItem* alarmItem = new QStandardItem(QIcon("res/alarmclock.ico"), alarmName); 
itemModel->setItem(rowCount - 1 , 0, alarmItem); 

// Date Time 
QStandardItem* dateTimeItem = new QStandardItem(); 
dateTimeItem->setText(alarmDateTime.toString()); 
dateTimeItem->setEditable(false); 
itemModel->setItem(rowCount - 1, 1, dateTimeItem); 

// Enabled 
QStandardItem* enabledItem = new QStandardItem(); 
QList<QStandardItem*> optionList; 
optionList << new QStandardItem("Enabled") << new QStandardItem("Disabled"); 
enabledItem->appendRows(optionList); 
itemModel->setItem(rowCount - 1, 2, enabledItem); 
} 

Sửa 1

qcomboboxdelegate.cpp

QWidget* QComboBoxItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) { 
// create widget for use 
qDebug() << "Column: " << index.column(); 
if (index.column() == 2) { 
    QComboBox* comboBox = new QComboBox(parent); 
    QStringList values; 
    values << "Enabled" << "Disabled"; 
    comboBox->addItems(values); 
    return comboBox; 
} else { 
    return QItemDelegate::createEditor(parent, option, index); 
} 
} 

mainwindow.cpp

void MainWindow::on_alarmDialog_close() { 
QList<QStandardItem*> row; 

QString alarmName = alarmDialog->getAlarmName(); 
QDateTime alarmDateTime = alarmDialog->getDateTime(); 
QString status = "Enabled"; 

// Alarm Name 
QStandardItem* alarmItem = new QStandardItem(QIcon("res/alarmclock.ico"), alarmName); 
row << alarmItem; 

// Date Time 
QStandardItem* dateTimeItem = new QStandardItem(); 
dateTimeItem->setText(alarmDateTime.toString()); 
dateTimeItem->setEditable(false); 
row << dateTimeItem; 

// Enabled 
QStandardItem* statusItem = new QStandardItem(status); 
row << statusItem; 

itemModel->appendRow(row); 
} 

Trả lời

9

Trước tiên, bạn cần phải có một mô tả các cột mô hình của bạn:

enum Columns 
{ 
    COL_NAME, 
    COL_TIME, 
    COL_STATUS 
} 

Bạn ủy quyền shoud chỉ hoạt động cho cột cuối cùng.

Dưới đây là một ví dụ về cách bạn có thể cư mô hình của bạn:

for (int i = 0; i < 5; ++i) 
{ 
    QStandardItem *itemName = new QStandardItem(QString("name %1").arg(i)); 
    QStandardItem *itemTime = new QStandardItem(QString("time %1").arg(i)); 

    QString status; 
    if (i % 2 == 0) 
    { 
     status = "Enabled"; 
    } 
    else 
    { 
     status = "Disabled"; 
    } 

    QStandardItem *itemStatus = new QStandardItem(status); 

    QList<QStandardItem*> row; 
    row << itemName << itemTime << itemStatus; 

    model->appendRow(row); 
} 

Như tôi đã nói, đại biểu của bạn chỉ nên làm việc cho cột cuối cùng. Vì vậy, tất cả các phương pháp bạn đã reimplemented nên có một tấm séc cột như thế này:

QWidget* QComboBoxItemDelegate::createEditor(QWidget *parent, 
          const QStyleOptionViewItem &option, 
          const QModelIndex &index) 
{ 
    if (index.column() == COL_STATUS) 
    { 
     QStringList values; 
     values << "Enabled" << "Disabled"; 

     QComboBox* comboBox = new QComboBox(parent); 
     comboBox->addItems(values); 
     return comboBox; 
    } 
    else 
    { 
     return QItemDelegate::createEditor(parent, option, index); 
    } 
} 

Bạn nên thêm việc kiểm tra này với các phương pháp khác: nếu cột hiện tại không phải là cột trạng thái, các lớp cơ sở (QItemDelegate) thực hiện, nếu được sử dụng .

Sau đó, bạn thiết lập đại biểu của bạn để xem bạn:

ui->tableView->setItemDelegate(new ComboBoxDelegate); 

Nếu bạn làm tất cả mọi thứ bên phải, một combobox sẽ xuất hiện ở cột cuối cùng nếu bạn cố gắng để chỉnh sửa giá trị của nó.

+0

Khi nào tôi giả sử gọi ui-> tableView-> setItemDelegate (new ComboBoxDelegate) ;? Tôi gọi nó trong SetupUI của tôi() được gọi trước khi tôi thêm bất cứ thứ gì vào tableView và sau khi thực hiện các thay đổi, nó vẫn không hoạt động. Tôi cũng đã thử nghiệm gọi nó sau appendRow() nhưng nó vẫn không hoạt động. Tôi đã đặt một số câu lệnh debug trong QComboxItemDelegate để xem nó đã đi bao xa nhưng createEditor() không được gọi là – arnm

+0

Cảm ơn sự trợ giúp! Tôi đã tìm ra vấn đề của tôi nhờ bạn – arnm

2

Vì vậy, tôi đã tìm ra rằng tôi đã không ghi đè lên các nguyên mẫu chức năng chính xác ..! Tôi quên rằng họ đã const trong nguyên mẫu có nghĩa là tôi đã không ghi đè bất kỳ chức năng vì vậy nó đã được sử dụng những mặc định. Dưới đây là các chức năng ảo chính xác phải được triển khai lại: http://qt-project.org/doc/qt-5.0/qtwidgets/qitemdelegate.html

+2

nếu bạn đã phát hiện ra vấn đề của mình nhờ hank bạn nên cho anh ta tín dụng và thay vì tự mình kiểm tra câu trả lời đúng, chỉnh sửa và/hoặc nhận xét câu trả lời của anh ấy/cô ấy. – refuzee

+3

Để ngăn chặn những vấn đề đó trong tương lai, tôi khuyên bạn nên sử dụng từ khóa 'override' của C++ 11. http://en.cppreference.com/w/cpp/language/override –

Các vấn đề liên quan