crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> создание делегата для QTableView на основе QTextEdit
Steklova Olga
  опции профиля:
сообщение 2.4.2012, 15:21
Сообщение #1


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Всем привет! :)
У меня в БД FireBird есть следующая таблица:
CREATE TABLE T_MSG_VC(
    F_RECORD_NMB      D_INTEGER NOT NULL,
    F_MSG_TEXT_VC     VARCHAR(1000) NOT NULL
);
Хочу ее отобразить в QTableView.
Оператор должен иметь возможность просмотра таблицы, а редактирование данных должно быть запрещено.
Для этого мне, видимо, нужно создать делегат.
Посмотрите, пожалуйста, для моего случая достаточно того, что я написала?
delegate.h
#ifndef DELEGATE_H
#define DELEGATE_H

#include <QtGui/QItemDelegate>

class TextEditDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    TextEditDelegate(QObject *parent = 0);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const;
};

#endif
delegate.cpp
#include <QtGui/QTextEdit>

#include "delegate.h"

TextEditDelegate::TextEditDelegate(QObject *parent)
    : QItemDelegate(parent)
{
}

QWidget *TextEditDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &/* option */,
    const QModelIndex &/* index */) const
{
    QTextEdit *editor = new QTextEdit(parent);

    return editor;
}
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    ...
    tableView = new QTableView();
    delegate = new TextEditDelegate();

    tableView->setItemDelegateForColumn(1, delegate);
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ...
}
...
Пока не говорю о размерах ячеек QTableView. Об этом позже... :)


Сообщение отредактировал Steklova Olga - 2.4.2012, 15:29
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 3.4.2012, 20:17
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Steklova Olga @ 2.4.2012, 17:21) *
Оператор должен иметь возможность просмотра таблицы, а редактирование данных должно быть запрещено.
Это достигается установкой триггеров редактирования - EditTriggers

Если же нужно ограничить редактирование определённых данных (строки или столбца) лучше сделать свою модель, которая переопределяет один единственный метод:
virtual Qt::ItemFlags flags ( const QModelIndex & index ) const

и для некторого(ых) индекса НЕ будет возвращать Qt::ItemIsEditable
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 3.4.2012, 21:29
Сообщение #3


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Спасибо, Юрий, это все понятно :)
А в классе TextEditDelegate ничего больше не надо переопределять (если, конечно, не нужно редактирование текста)?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 4.4.2012, 11:24
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


если сделаешь свою модель, то свой делегат вообще не нужно делать, если, конечно, он не специфический.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 4.4.2012, 12:21
Сообщение #5


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


И все же, если я остановлюсь на использовании моего делегата, простого до крайности, то вот этого достаточно?
QWidget *TextEditDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &/* option */,
    const QModelIndex &/* index */) const
{
    QTextEdit *editor = new QTextEdit(parent);
    return editor;
}

Цитата
если сделаешь свою модель, то свой делегат вообще не нужно делать, если, конечно, он не специфический.
И как мне без использования делегата указать в модели, что при ее отображении в QTableView надо будет использовать QTextEdit?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
wiz29
  опции профиля:
сообщение 4.4.2012, 15:51
Сообщение #6


Старейший участник
****

Группа: Участник
Сообщений: 600
Регистрация: 7.7.2010
Из: Санкт-Петербург
Пользователь №: 1866

Спасибо сказали: 94 раз(а)




Репутация:   12  


Если внутри QVariant будет строка то фабрика по умолчанию создаст делегат для строк как QLineEdit.

см. тут
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 4.4.2012, 17:52
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Steklova Olga, ты про делегат не правильно понимаешь.

Коротко:
Делегат - класс, объект которого создаёт представление, этот класс в обычном режиме рисует элемент данных в определённом месте представления (получая данные непосредственно из модели).
Рисование элемента осуществляется в функции делегата paint().
Когда пользователь переходит в режим редактирования данных (а тебе это не нужно), представление вызывает у делегата целую пачку методов, начиная с createEditor(), которая просто создаёт виджет-редактор.

Виджет-редактор - виджет, который создаётся делегатом только для редактирования данных. По завершении редактирования виджет-редактор разрушается.


Поняла?

П.С.
Только сейчас стал понимать, в чём проблема (описаная в другой теме) в твоём делегате. Видимо ты создаёшь объект QTextEdit в качестве виджета-редактора, и ожидаешь что делегат в обычном режиме будет себя вести как QTextEdit. Хотя делегат в этом режиме самостоятельно занимается рисованием элемента на экране.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 4.4.2012, 21:42
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Спасибо большое, Юрий, в общих чертах поняла! Ура! :clapping::D

Так как представление у меня редактировать не надо, то делегата для редактирования мне не нужно,
надо просто указать подходящий режим для представления:
tableView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
Жаль только, что он работает, по-моему, кривовато, что я предлагаю добить вот в этой теме
(05.04.2012 добили, делегат все-таки понадобился для отображения, в нем переопределен метод drawDisplay)

А когда мне понадобится редактировать данные в представлении, прямо на экране, то мне НЕ ПОМЕШАЕТ ПОЧИТАТЬ про делегаты подробно, а не просто бездумно списывать. :)

wiz29, спасибо за ссылку, но для редактирования поля типа VARCHAR(1000) делегат для строк как QLineEdit не очень-то подойдет, для этого нужен QTextEdit. Потому что неудобно редактировать такой длинный текст в одной строке.

Сообщение отредактировал Steklova Olga - 5.4.2012, 17:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 5.4.2012, 16:28
Сообщение #9


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


wiz29, а вот что я заметила в части использования QLineEdit в качестве делегата:

1. Если не создавать делегат вручную, но начать редактирование поля типа VARCHAR(1000), то, действительно, на экране появится QLineEdit в этой ячейке,
но, если до выхода из редактирования расширить или сузить мышью окно, то ширина QLineEdit останется такой, как она была до изменения размера окна, а из под него будет видна часть многострочного текста (см рис1).

2. Если создать класс делегата, указав в createEditor
QLineEdit *editor = new QLineEdit(parent);
установить этот делегат для колонки представления, начать редактирование поля типа VARCHAR(1000), то на экране появится QLineEdit в этой ячейке, а, если до выхода из редактирования расширить или сузить мышью окно, то ширина QLineEdit будет корректно меняться в соотв. с меняющимися размерами окна (см рис2).
Получается, что 2-й вариант предпочтительнее :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.4.2024, 2:52