crossplatform.ru

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


  Ответ в изменение высоты ячеек QTableView, для которого установлен делегат на основе QTextEdit
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
wiz29 Дата 18.4.2012, 15:32
  Да наверное так и есть, скачал не ту версию. :)
Steklova Olga Дата 18.4.2012, 14:43
  Да, wiz29, теперь заработало, ура-а-а! Благодарю! :clapping:

Только в drawDisplay надо внести изменение, которое Вы раньше уже вносили, а сейчас забыли (видимо, взяли не последний прикрепленный файл из сообщения 9, а предпоследний из сообщения 7):
    //было painter->setPen(option.palette.color(cg, QPalette::Text));
    //стало
    if (option.state & QStyle::State_Selected) {
        painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
    }
    else {
        painter->setPen(option.palette.color(cg, QPalette::Text));
    }

И правильнее будет написать
    //было delegate = new TextEditDelegate();
    //стало
    delegate = new TextEditDelegate(this);
wiz29 Дата 18.4.2012, 12:56
  Этот вариант рабочий, если где то будет что то криво, то нужно исправлять функцию делегата, вычисляющую предпочтительные размеры для ячейки.
Steklova Olga Дата 18.4.2012, 11:41
  wiz29, код тестового примера по прежнему можно взять в Вами прикрепленном файле в 9-ом сообщении этой темы.
Надо только внести следующее изменение в код:
        case 1:
            model->setData(index, QVariant(
                    "ЗДРАВИЯ ЖЕЛАЮ, ТОВАРИЩ КОМАНДИР!"));
                    //"Абв"
                    //"  PRIVETPRIVET 1 01234"
                    //"  PRIVET 2 01234"
                    //"  PRIVET 3 01234"
                    //"  PRIVET 4 01234"));
                    break;
wiz29 Дата 18.4.2012, 11:25
  Нужен код тестового проекта, к сожалению у меня его не сохранилось.
Steklova Olga Дата 18.4.2012, 11:06
  wiz29, :) извините, пожалуйста, но Ваш код все-таки не всегда срабатывает. Посмотрите, что получается при увеличении ширины окна:
Steklova Olga Дата 5.4.2012, 18:43
  Snake174, или Вы не правы, или я не знаю...
То, что написано у Вас в коде совсем не подходит. Посмотрите:
mymodel1.h
#ifndef MYMODEL1_H
#define MYMODEL1_H

#include <QStandardItemModel>

class MyModel1 : public QStandardItemModel
{
    Q_OBJECT
public:    
    explicit MyModel1(QObject *parent = 0);

    //второй конструктор (не использую)
    //MyModel1(int rows, int columns, QObject *parent = 0);

    QVariant data(const QModelIndex &index,
                  int role = Qt::DisplayRole) const;
};

#endif // MYMODEL1_H
mymodel1.cpp (привожу два варианта метода data)
#include "mymodel1.h"
#include <QtGui/QFontMetrics> //у него не было
#include <QtGui/QApplication> //у него не было

MyModel1::MyModel1(QObject *parent) :
    QStandardItemModel(parent)
{
}

//Попробуй в своей модели установить SizeHintRole:

//это ваш вариант в том виде, как я его поняла, он не работает
QVariant MyModel1::data(const QModelIndex &index,
                        int role/*у него нет = Qt::DisplayRole*/) const {

  //у него нет QVariant value = QStandardItemModel::data(index, role);

  //у него нет switch

  //у него есть зачем-то
  if (!index.isValid())
    //что это?
    return QVariant();

  //у него так, но это не работает
  //if (index.row() >= static_cast<int>( количество строк )
  //if (index.row() >= static_cast<int>(5)
  if (index.row() >= 5/* количество строк */)
      //что это?
    return QVariant();

  if (index.column() >= 2/*количество столбцов*/)
      //что это?
    return QVariant();

  if (role == Qt::DisplayRole || role == Qt::ToolTipRole || role == Qt::StatusTipRole)
  {
    for (register int i = 0; i < 2/*количество столбцов*/; ++i)
    {
      if (index.column() == i)
        //у него было
        //return текстовые данные;
        return QString("текстовые данные");
    }
  }

  if (role == Qt::SizeHintRole)
  {
    QFontMetrics fm( QApplication::font() );

    //у него было
    //int h = fm.boundingRect( текстовые данные ).height();
    int h = fm.boundingRect(QString("текстовые данные")).height();

    QSize defSize;
    defSize.setHeight( h + 4 );

    return defSize;
  }

  //что это?
  return QVariant();
}



////переделанный мною ваш вариант, он тоже не работает
//QVariant MyModel1::data(const QModelIndex &index,
//                        int role) const {

//  //по-моему, этого здесь не хватает
//  QVariant value = QStandardItemModel::data(index, role);
//  QVariant valueForDisplayRole = QStandardItemModel::data(index, Qt::DisplayRole);

//  //а потом, по-моему, было написано много лишнего,
//  //что я убрала

//  switch (role) {

//  case Qt::SizeHintRole: //
//      QFontMetrics fm( QApplication::font() );
//      QSize defSize;

//      //вы здесь просто берете высоту одной строки текста
//      int h = fm.boundingRect(valueForDisplayRole.toString()).height();

//      //по-моему, этого здесь не хватает
//      defSize = value.toSize();

//      //а здесь вы к высоте одной строки текста + const
//      defSize.setHeight( h + 50 ); //заменила на 50 для наглядности

//      //в результате высота всех строк у вас всегда одинаковая,
//      //равная высоте одной строки текста + const
//      return defSize;

//  } //switch (role)

//  return value;
//}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>

class QStandardItemModel;
class QTableView;

//#include "delegate.h"
#include "mymodel1.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    //QStandardItemModel* model;
    MyModel1* model;
    QTableView* tableView;
    //TextEditDelegate* delegate;
};

#endif // MAINWINDOW_H
mainwindow.cpp
#include <QtGui/QStandardItemModel>
#include <QtGui/QTableView>
#include <QtGui/QHeaderView>

#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
//    model = new QStandardItemModel(5, 2);

//    model = new QStandardItemModel();
//    model->setRowCount(5);
//    model->setColumnCount(2);

    model = new MyModel1();
    model->setRowCount(5);
    model->setColumnCount(2);

    tableView = new QTableView();
//    delegate = new TextEditDelegate();

    for (int row = 0; row < 5; ++row) {
        for (int column = 0; column < 2; ++column) {
            QModelIndex index = model->index(row, column, QModelIndex());
            switch(column)
            {
            case 0:
                model->setData(index, QVariant(
                        row+1)); break;
            default:
                switch(row)
                {
                case 0:
                    model->setData(index, QVariant(
                            "")); break;
                case 1:
                    model->setData(index, QVariant(
                            "Абв"
                            "  PRIVETPRIVET 1 01234"
                            "  PRIVET 2 01234"
                            "  PRIVET 3 01234"
                            "  PRIVET 4 01234")); break;
                case 2:
                    model->setData(index, QVariant(
                            "PRIVET PRIVET 1 01234"
                            "  Абв"
                            "  PRIVET 2 01234"
                            "  PRIVET 3 01234"
                            "  PRIVET 4 01234")); break;
                case 3:
                    model->setData(index, QVariant(
                            "Абв"
                            "  PRIVETPRIVET 1 01234"
                            "  PRIVET 2 01234"
                            "  PRIVET 3 01234")); break;
                default:
                    model->setData(index, QVariant(
                            "Абв"
                            "  PRIVETPRIVET 1 01234"
                            "  PRIVET 2 01234"
                            "  PRIVET 3 01234"
                            "  PRIVET 4 01234")); break;
                }
                break;
            }
        }
    }

    tableView->setModel(model);
//    tableView->setItemDelegateForColumn(1, delegate);
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);

    tableView->resizeColumnToContents(0);
    tableView->horizontalHeader()->setStretchLastSection(true);

    tableView->verticalHeader()->hide();
    tableView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
    //tableView->setTextElideMode(Qt::ElideNone);

    if (model->rowCount() > 0)
        tableView->setCurrentIndex(model->index(0, 0));

    setCentralWidget(tableView);

    setWindowTitle("Text Edit Delegate");
    setGeometry(100, 250, 170, 500);
}

MainWindow::~MainWindow()
{

}

Steklova Olga Дата 5.4.2012, 17:03
  Благодарю, Вас, wiz29 ! Теперь просмотр поля типа VARCHAR(1000) в QTableView чудно работает ! :clapping:
P.S. внесла дополнение в свое сообщение 8
wiz29 Дата 5.4.2012, 15:46
 
Цитата(Steklova Olga @ 5.4.2012, 16:07) *
что в Вашем примере надо поменять, чтобы при просмотре представления цвет текста в выбранной строке в колонке с делегатом становился (как это принято) белым, а не так, как сейчас (черным) (см. рис)?


Модификация.
Steklova Olga Дата 5.4.2012, 15:07
  Спасибочки, wiz29, Вы очень умный! :give_rose:
При просмотре текст теперь отображается так, как было задумано.
Вот только я еще даже не смотрела класс QPainter. Посмотрю.
Надо мне хотя-бы книжку Земскова "Qt на примерах" полностью прочитать, а не писать программу интуитивно, бегая по верхам помощи (по классам Qt), книжек, форума и googlе :)

Есть только маленький вопросик сейчас: что в Вашем примере надо поменять, чтобы при просмотре представления цвет текста в выбранной строке в колонке с делегатом становился (как это принято) белым, а не так, как сейчас (черным) (см. рис)?


1. На будущее, если делать представление редактируемым,
то недостаточно переопределить только createEditor и drawDisplay так, как сейчас.

2. Сейчас мое представление не редактируемое,
поэтому переопределение createEditor в этом варианте я убрала, как совершенно не нужное.

3. Рассказываю дальше, зачем все это надо.
У меня в таблице БД сохраняется переписка двух абонентов (их сообщения друг другу в виде простого текста (не html), время посылки сообщения, ID написавшего сообщение абонента).
В соотв. с моим алгоритмом, в процессе переписки эту таблицу отображать не надо.
После окончания переписки (я знаю, когда это произойдет) надо отобразить таблицу сообщений.
Сначала надо отобразить все сообщения.
После этого можно будет их сортировать / фильтровать (это я знаю, как сделать).

Но вот я думаю, что, так как сообщения могут быть достаточно длинными, хорошо бы было предусмотреть возможность двух вариантов отображения сообщений и переключения между ними с помощью группы кнопок "Сокращенно", "Полностью".
Сначала отобразить все сообщения в первом варианте, сокращенно (каждое - в одну строку, с "..."),
при нажатии кнопки "Полностью" отобразить все сообщения во втором варианте, полностью,
при нажатии кнопки "Сокращенно" вернуться к первому варианту.
Мне кажется, это было бы очень удобно.
:D
Принимаются предложения, как прикрутить к имеющемуся коду сокращенный вариант.

А перерисовку может сократить как-то? Или не стоит об этом беспокоиться?
Например, не постоянно пересчитывать, как отобразить текст в процессе изменения размера окна,
а сделать это сначала при первом отображении таблицы сообщений,
а следующий раз (в случае изменения размера окна) сделать по окончании изменения размера окна, при отпускании мыши.


И еще, пока что, открыт вопрос, как корректно сохранять сообщения неизвестной заранее длины в БД Firebird 2.1 и отображать их потом в представлении (там проблемы с русским текстом и, видимо, с драйвером), об этом моя тема тут.
Если бы этот вопрос решился, то я вместо работы с сообщениями длиной не более 1000 символов,
перешла бы к работе с сообщениями, неограниченными по длине. Так надо по алгоритму.
И тогда эта ветка программы была бы доделана. ;)
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 29.3.2024, 18:54