Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Работа с QTableWidget


Автор: gordmiand 4.10.2011, 20:47
У меня 2 вопроса:
1. Каким образом можно сделать так, чтобы СРАЗУ по ОДНОКРАТНОМУ клику в ячейке она бы переходила в режим редактирования (то есть режим ввода данных в нее) – по умолчанию сначала надо один раз кликнуть на нужной ячейке (типа выбрать ее), а потом еще раз кликнуть по ней же для перехода в режим ввода данных….
2. Как можно сделать так, чтобы введенное в ячейку значение считывалось бы (допустим в какую-то переменную) даже без “признака окончания редактирования данных” – это “Enter” после ввода данных в ячейку или клик вне ее – то есть чтобы было достаточно для корректного считывания наличия текста в ячейке (то есть получается что когда ячейка находится еще в режиме редактирования, но это должно быть неважно – допустим, если это значение считывается из ячейки по кнопке, то в переменную должно записаться текущее на момент клика значение из ячейки)…
Код

int data;
data =  ui->tableWidget->item(0,0)->text().toInt() ;

Для решения второго вопроса я уже перебрал всевозможный стандартные слоты таблицы – cellClicked, cellActivated, cellChanged, cellEntered, cellPressed…, да не один из них мне вроде как не подошел (может я их неверно использую…) – некоторые из них наступают только после описанного мной выше “завершающего ввод данных признака”, а другие вообще непонятно когда наступают…   

Автор: math64 4.10.2011, 22:07
1. Вешай слот на сигнал clicked(), cellClicked() или itemClicked() и вызывай edit()
2. Создай делегата class Delegate : public StyledItemDelegate {} и в Delegate::createEditor() на соотвествующий сигнал созданного редактора например QSpinBox::dataChanged() вешай свой слот и сохраняй данные куда хочешь например QGraphicsItem::setPos() для перемещения его на сцене по горизонтали или вертикали.

Автор: math64 4.10.2011, 22:30
На первый вопрос: можно сделать проще, вызвать setEditTriggers() для выбора соответсвующего свособа открытия редактора.

Автор: gordmiand 4.10.2011, 23:27
math64: за ответ на первый вопрос спасибо - сделал через setEditTriggers(AbstractItemView::CurrentChanged)

по поводу второго вопроса - дайте пож-та простейший примерчик решения данной задачки, а то я по Вашим словам не совсем все понял...

Автор: math64 5.10.2011, 07:28
Код

class Delegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit Delegate(QObject* parent = NULL);
    virtual ~Delegate();
    virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
        // Для типа int стандартный делегат создаёт QSpinBox - устраивает - создаём стандартный редактор
        QWidget* editor = QStyledItemDelegate::createEditor(parent, option, index);
        if (qobject_cast<QSpinBox*>(editor) != NULL) {
            // Настраиваем редактор
            QSpinBox* sb = qobject_cast<QSpinBox*>(editor);
            sb->setMinimum(minimum);
            sb->setMaximum(maximum);
            QObject::connect(editor, SIGNAL(valueChanged(int)), this, SLOT(editorDataChanged()));
            savedEditor = editor;
        }
        return editor;
    }
    // Копирование данных из модели в редактор
    virtual void setEditorData(QWidget *editor, const QModelIndex &index) const {
        QStyledItemDelegate::setEditorData(editor, index);
    }
    // Копирование данных из редактора в модель
    virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
        QStyledItemDelegate::setModelData(editor, model, index);
    }
    // Настройка размеров редактора
    virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
        Q_UNUSED(index);
        editor->setGeometry(option.rect);
    }
private:
    int data;
    int minimum;
    int maximum;
    mutable QWidget* savedEditor;
private slots:
    void editorDataChanged() {
        if (qobject_cast<QSpinBox*>(savedEditor) != NULL) {
            QSpinBox* sb = qobject_cast<QSpinBox*>(savedEditor);
            data = sb->value();
        }
    }
};

delegate = new Delegate();
ui->tableWidget->setItemDelegate(delegate);

Автор: gordmiand 5.10.2011, 20:40
math64 - спасибо, конечно, за предоставленный пример решения вопроса №2, но неужели нельзся его решить как-то попроще? Ваш пример уж больно объемный и сложный - для такой-то вроде несложной задачки...

Автор: math64 5.10.2011, 21:04
Главное в коде:
Код

            QObject::connect(editor, SIGNAL(valueChanged(int)), this, SLOT(editorDataChanged()));

Если найдёшь более простой способ получить указатель на редактор - используй его. 
В данном примере можно убрать setEditorData(), setModelData() updateEditorGeomery() - я просто продамонстрировал, что такие методы есть, в некоторых случаях можно в них что-то изменить (это нужно, если стандартный редактор не подходит)
Останется только метод createEditor().
(см. пример spinboxdelegate из примеров Qt)
Другой способ - создать свою фабрику редакторов (пример coloreditorfactory)
Но если зарегистрировать свою фабрику в качестве фабрики по умолчанию, как в этом примере, она будет использоваться во всех списках, таблицах, деревьях, что не всегда нужно. И код получится не намного меньше.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)