crossplatform.ru

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


  Ответ в Табличное представление с виджетами
Введите ваше имя
Подтвердите код

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

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


Последние 10 сообщений [ в обратном порядке ]
abc Дата 18.2.2011, 22:16
  событие можно так создать:
QCoreApplication::sendEvent
в остальное я не вник)
Алексей1153 Дата 8.2.2011, 19:18
 
Цитата(Vorchun @ 8.2.2011, 17:56) *
Была идея, что надо отлавливать mousePressEvent()

только там имхо и надо. Но не пресс, а релиз только лучше
Vorchun Дата 8.2.2011, 15:56
  Задача: Создать на базе модель представления таблицу из виджетов, таким образом чтоб она по функциональности не отличалась от виджетов помещенных в gridlayout

Частичное решение
Существует контейнер в котором хранится List из CalendarI

Существует модель ( прослойка между представлением и контейнером) умеющая через data() возвращать CalendarI
Существует виджет CalendarIW который умеет отображать CalendarI ( setItem() ) - у меня это виджет с кнопочками

Я сделал следующий делегат (немного криво, но в целом вполне функционально ):

CalendarD::CalendarD( QObject *qoParent )
: QStyledItemDelegate( qoParent )
{}

CalendarD::~CalendarD() {}

//virtual
void CalendarD::paint( QPainter *qpPainter
                     , const QStyleOptionViewItem &qsoviOption
                     , const QModelIndex &qmiIndex ) const
{
if ( ! qmiIndex.data( Qt::EditRole ).isValid() ) return;

QPalette qpPalette = qsoviOption.palette;

qpPalette.setBrush( QPalette::Window
                   , qpPalette.brush( QPalette::Base ) );

CalendarIW *ciw = new CalendarIW();
ciw->setPalette( qpPalette );
ciw->setItem( qmiIndex.data( Qt::EditRole ).value< CalendarI >() );
ciw->resize( qsoviOption.rect.size() );

qpPainter->save();
qpPainter->translate( qsoviOption.rect.topLeft() );
qpPainter->setClipRect( qsoviOption.rect.translated( -qsoviOption.rect.x()
                                                    , -qsoviOption.rect.y() ) );
ciw->render( qpPainter );

qpPainter->restore();

delete ciw;

}

//virtual
QSize CalendarD::sizeHint( const QStyleOptionViewItem &qsoviOption
                         , const QModelIndex &qmiIndex ) const
{
CalendarI ci( qmiIndex.data( Qt::EditRole ).value< CalendarI >() );

CalendarIW *ciw = new CalendarIW();
ciw->setItem( ci );

return ( ci.type() != CalendarI::Day )
        ? QSize( 0, 0 )
        : ciw->sizeHint();

delete ciw;
}

QWidget *CalendarD::createEditor( QWidget *qwParent
                                , const QStyleOptionViewItem &
                                , const QModelIndex &qmiIndex ) const
{
CalendarIW *ciw = new CalendarIW( qwParent );
ciw->setAutoFillBackground( true );
ciw->setMouseTracking( true );
return ciw;
}

void CalendarD::setEditorData( QWidget *qwEditor
                             , const QModelIndex &qmiIndex ) const
{
CalendarIW *ciw = dynamic_cast< CalendarIW * >( qwEditor );

Q_ASSERT( ciw );

CalendarI ci( qmiIndex.data( Qt::EditRole ).value< CalendarI >() );

ciw->setItem( ci );
}

void CalendarD::setModelData( QWidget *qwEditor
                            , QAbstractItemModel *qaimModel
                            , const QModelIndex &qmiIndex ) const
{}

void CalendarD::updateEditorGeometry( QWidget *qwEditor
                                    , const QStyleOptionViewItem &qsoviOption
                                    , const QModelIndex & ) const
{ qwEditor->setGeometry( qsoviOption.rect ); }

//protected:

bool CalendarD::eventFilter( QObject *qoEditor , QEvent *qeEvent )
{

if ( qeEvent->type() == QEvent::Leave )
{
  QWidget *qwWidget = qobject_cast< QWidget * >( qoEditor );

  emit closeEditor( qwWidget
                  , QAbstractItemDelegate::RevertModelCache );
  return true;
}

return QStyledItemDelegate::eventFilter( qoEditor , qeEvent );
}


коротко - этот делегат отрисовывает как нужно ячейку, когда она не редактируется, а когда она редактируется - он создает виджет, который обеспечивает необходимый функционал.

bool CalendarD::eventFilter( QObject *qoEditor , QEvent *qeEvent ) - обеспечивает выход из виджета, когда мышь покидает область редактирования

Открывать ячейку на редактирование планировалось из представления следующим образом

CalendarV::CalendarV( QWidget *qwParent )
: QTableView( qwParent )
{
setMouseTracking( true );
connect( this, SIGNAL( entered( const QModelIndex & ) ), this , SLOT( openEditor(  const QModelIndex &  ) )  );

//public slots:
void CalendarV::openEditor(  const QModelIndex & qmiIndex )
{
  if (  state() != QAbstractItemView::NoState
     || ! qmiIndex.isValid()
     || ! qmiIndex.flags() & Qt::ItemIsEditable ) return;

edit( qmiIndex );
}


При таком подходе - юзер водит мышью по вьюву тыкает на кнопочки в виджетах - и вообще не догадывается что перед ним не Gridlayout. Это работает при медленном движении мыши. Все было бы хорошо если бы не одно НО - при быстром движении мыши возникает следующая ситуация:
1) мышь пролетает по первой ячейке - создается первая ячейка
2) мышь продолжает лететь - пока первая ячейка еще не создалась или еще хз почему - но мышь уже покинула эту ячейку - соответственно виджет редактора из делегата не получил событие QEvent::Leave приведшее к его уничтожению, те первая ячейка продолжает редактироваться
3) поскольку первая ячейка еще редактируется - все остальные ячейки не открываются на редактирование...

Вот!

Была идея, что надо отлавливать mousePressEvent() - открывать ячейку на редактирование, а потом повторно создавать событие нажатие мыши, чтоб его отловил уже открытый виджет - но как это сделать я не в курсе...

Есть ли у кого какие либо идеи еще?



Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 19.4.2024, 4:44