Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: INZER от Апреля 14, 2012, 15:15



Название: [ЗАКРЫТО] Поворот текста в QTableView
Отправлено: INZER от Апреля 14, 2012, 15:15
Привет всем!
Хочу чтобы текст в QTableView был повернут на 90 градусов ..
направьте в нужную сторону


Название: Re: Поворот текста в QTableView
Отправлено: GreatSnake от Апреля 14, 2012, 15:23
QStyledItemDelegate + это (http://doc.crossplatform.ru/qt/4.7.x/model-view-programming.html#delegate-classes) + QPainter::rotate().


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Апреля 15, 2012, 13:08
переопределил метод paint
Однако текст в таблице не повернулся  >:(
Не тот метод переопределил?
Код  представил ниже

Результат следующий:
(http://i33.fastpic.ru/big/2012/0415/e6/c1b05b02aaaf4e4dae3b66dad20997e6.png)

Хотелось бы повернуть только текст )).... заранее спасибо

Код:
class ProjItemDelegate: public QStyledItemDelegate
{
    Q_OBJECT
public:
    ProjItemDelegate();
    virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

void ProjItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV4 opt = QStyleOptionViewItemV4(option);
    initStyleOption(&opt, index);
    const QWidget *widget = opt.widget;
    QStyle *style = widget ? widget->style() : QApplication::style();
    painter->rotate(10);
    painter->save();
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter);
    painter->restore();
}

ui->tbProjectPlan->setModel(projManageProj);
ui->tbProjectPlan->setItemDelegate(new ProjItemDelegate());


Название: Re: Поворот текста в QTableView
Отправлено: Bepec от Апреля 15, 2012, 21:58
Эффект радует :) И веселит.


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Апреля 16, 2012, 08:44
Было бы весело, если бы не было так грустно :)))
Есть еще какие нибудь идеи?
С делегатами вроде разобрался но полезного пока ничего не нашел
Можно ли повернуть текст в QtextEdit?
Или может тупо табличку повернуть на 90 градусов .. мн не принципиально главное чтобы текст писался снизу вверх)


Название: Re: Поворот текста в QTableView
Отправлено: asvil от Апреля 16, 2012, 09:12
Необходимо сначала
Код:
QString text = opt.text;
opt.text.clear();
....
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter);
Затем нужно отрисовать повернутый текст, c помощью, например, Label


Название: Re: Поворот текста в QTableView
Отправлено: GreatSnake от Апреля 16, 2012, 12:53
Вот рабочий пример:
Код
C++ (Qt)
#include <QApplication>
#include <QHeaderView>
#include <QPainter>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <QStyleOptionViewItemV4>
#include <QTableView>
 
class ItemDelegate : public QStyledItemDelegate
{
public:
ItemDelegate( QObject* p = 0 )
: QStyledItemDelegate( p ) {}
 
protected:
void paint(
QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const
{
QWidget* widget = qobject_cast< QWidget* >( parent() );
QStyle *style = widget ? widget->style() : QApplication::style();
 
QStyleOptionViewItemV4 opt = option;
initStyleOption( &opt, index );
 
QRect textRect = style->subElementRect( QStyle::SE_ItemViewItemText, &opt, widget );
 
QString text = opt.text;
opt.text.clear();
 
style->drawControl( QStyle::CE_ItemViewItem, &opt, painter, widget );
 
bool is_enabled = opt.state & QStyle::State_Enabled;
QPalette::ColorGroup cg = is_enabled ? QPalette::Normal : QPalette::Disabled;
if( cg == QPalette::Normal && !( opt.state & QStyle::State_Active ) )
cg = QPalette::Inactive;
 
painter->save();
 
painter->setClipRect( opt.rect.adjusted( 1, 1, -1, -1 ) );
QRect tr = painter->fontMetrics().boundingRect( text );
tr = QRect(
opt.rect.x() + ( opt.rect.width() - tr.height() ) / 2,
opt.rect.y() + ( opt.rect.height() - tr.width() ) / 2,
tr.height(), tr.width() );
painter->translate( tr.right() - 2, tr.bottom() );
painter->rotate( 270 );
 
if( opt.state & QStyle::State_Selected )
painter->setPen( opt.palette.color( cg, QPalette::HighlightedText) );
else
painter->setPen( opt.palette.color( cg, QPalette::Text ) );
painter->drawText( 0, 0, text );
 
painter->restore();
}
QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
QSize sz = QStyledItemDelegate::sizeHint( option, index );
return QSize( sz.height(), sz.width() );
}
};
 
int main( int argc, char** argv )
{
QApplication app( argc, argv );
 
QTableView tv;
QStandardItemModel m;
 
tv.setModel( &m );
tv.setItemDelegate( new ItemDelegate( &tv ) );
tv.setEditTriggers( QAbstractItemView::NoEditTriggers );
 
int rc = 20;
 
m.setColumnCount( rc );
m.setRowCount( rc );
 
for( int r = 0; r < rc; r++ )
for( int c = 0; c < rc; c++ )
{
QModelIndex mi = m.index( r, c );
m.setData( mi, QString( "%1:%2" ).
arg( r + 1, 2, 10, QChar( '0' ) ).
arg( c + 1, 2, 10, QChar( '0' ) ), Qt::DisplayRole );
}
 
tv.verticalHeader()->resizeSections( QHeaderView::ResizeToContents );
tv.horizontalHeader()->resizeSections( QHeaderView::ResizeToContents );
 
tv.show();
return app.exec();
}
 


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Апреля 19, 2012, 19:44
GreatSnake, спасибо!


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Мая 20, 2012, 19:50
Подскажите как заставить редактировать значения ячеек
Переопределил
Код:
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index)
но такое ощущение что этого мало, ячейки не становятся доступными для редактирования


Название: Re: Поворот текста в QTableView
Отправлено: GreatSnake от Мая 20, 2012, 20:48
см. QAbstractItemView::setEditTriggers().


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Мая 20, 2012, 22:22
GreatSnake, еще раз спасибо !!!


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Июня 12, 2012, 15:14
Столкнулся со следующей проблемой:
Необходимо сделать таблицу редактируемой.
Стандартное поведение не устраивает тем что необходимо сделать проверку на корректность введенных данных:

(http://s019.radikal.ru/i620/1206/10/1f64deac1d33.png)


Необходимо в первой строке использовать QDateEdit
Во второй QLineEdit
А во второй и третьей QComboBox

Код делегата:

Код:
    QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {

        if (index.row() == 0)
        {
            QDateEdit * dt = new QDateEdit(parent);

            return dt;
        }
        else if (index.row() == 2)
        {
            QComboBox * cmbBox = new QComboBox (parent);
            sqlMod->setQuery("SELECT CONCAT(surname, ' ', SUBSTR(name,1,1), '. ', SUBSTR(middle_name,1,1), '.') AS list, id FROM personal WHERE id<>1 AND id<>2 ORDER BY list;");
            cmbBox->setModel(sqlMod);
            return cmbBox;
        }
        else if (index.row() == 3)
        {
            QComboBox * cmbBox = new QComboBox (parent);
            sqlMod->setQuery("SELECT CONCAT(surname, ' ', SUBSTR(name,1,1), '. ', SUBSTR(middle_name,1,1), '.') AS list, id FROM personal WHERE id<>1 AND id<>2 ORDER BY list;");
            cmbBox->setModel(sqlMod);
            return cmbBox;
        }
        else
        {
            QLineEdit * edit = new QLineEdit (parent);
            return edit;
        }

    }

Результат:

(http://s017.radikal.ru/i406/1206/74/dad4fa34560d.png)

Как видите проблема в том что ширина элемента не меняется при редактировании и вообще не видно что вводишь. Как сделать так, чтобы виджет вел себя как при стандартном редактировании.
Как решить данную проблему ... направьте в какую сторону копать.


Название: Re: Поворот текста в QTableView
Отправлено: GreatSnake от Июня 13, 2012, 10:36
В createEditor() выстави у созданного редактора:
Код
C++ (Qt)
QSize sz = ew->sizeHint();
ew->setMinimumSize( sz );
ew->setMaximumHeight( sz.height() );
 

или ещё лучше перегрузи
Код
C++ (Qt)
void updateEditorGeometry( QWidget* w,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const
{
QSize sz = w->sizeHint();
w->setGeometry( QRect(
option.rect.x() + sz.width() < w->parentWidget()->width() ?
option.rect.x() : w->parentWidget()->width() - sz.width(),
option.rect.y() + ( option.rect.height() - sz.height() ) / 2,
sz.width(),
sz.height() ) );
}
 


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Июня 13, 2012, 14:36
GreatSnake, ты просто спаситель, спасибо еще раз!

Да, второй вариант поинтереснее смотрится.
осталось разобраться как отследить редактирование последних столбцов и подвинуть поле

(http://s017.radikal.ru/i421/1206/1f/fdc1a898033d.png)


Название: Re: Поворот текста в QTableView
Отправлено: GreatSnake от Июня 13, 2012, 14:47
осталось разобраться как отследить редактирование последних столбцов и подвинуть поле
Дык всё легко, см. выше.


Название: Re: Поворот текста в QTableView
Отправлено: INZER от Июня 13, 2012, 15:23
DONE! )))

Код:
w->move(option.rect.x()+option.rect.width()-w->width(),option.rect.y() + ( option.rect.height() - sz.height() ) / 2);


Название: Re: [ЗАКРЫТО] Поворот текста в QTableView
Отправлено: GreatSnake от Июня 13, 2012, 15:37
Код:
w->move(option.rect.x()+option.rect.width()-w->width(),option.rect.y() + ( option.rect.height() - sz.height() ) / 2);
В этом случае, если часть ячейки окажется за viewport-ом, то часть редактора окажется там же.