Russian Qt Forum

Qt => Общие вопросы => Тема начата: demaker от Сентябрь 05, 2016, 17:12



Название: QItemDelegate выделение текста надписи при фильтрации
Отправлено: demaker от Сентябрь 05, 2016, 17:12
Есть модель, у нее есть прокси модель, в которой реализован метод фильтрации
Код:
void filterAcceptsRow(int , const QModelIndex);

Кликаем по вьюшки вылетает окно фильтра (filterWidget)
Код
C++ (Qt)
 
void TableView::mouseDoubleClickEvent(QMouseEvent *event)
{
   if(event->button() == Qt::RightButton){
       if(filterWidget != NULL){
           delete  filterWidget;
           filterWidget = NULL;
       }
 
       QString nameTable = ((SqlTableModel*)(((DataBaseFilterModel*)model())->sourceModel()))->getNameTable();
       filterWidget = new FilterWidget(nameTable,nameColumn,column,0);
       connect(filterWidget,SIGNAL(changeFilter(QString ,int)),((DataBaseFilterModel*)model()),SLOT(updateFilterColumn(QString ,int)));
       connect(filterWidget,SIGNAL(closeWidget()),this,SLOT(closeFilterWidget()));
       filterWidget->show();
 
   }
 
   QTableView::mouseDoubleClickEvent(event);
}
 

при изменении текста в нем - фильтр прокси обновляется соответственно
вот сам фильтр-виджет
Код
C++ (Qt)
FilterWidget::FilterWidget(QString nameTable ,QString nameColumn, int numColumn, QWidget *parent) :
   QWidget(parent),
   ui(new Ui::FilterWidget)
{
   qDebug()<<__FUNCTION__;
 
   ui->setupUi(this);
 
   setWindowTitle(nameTable);
   ui->nameColumn->setText(nameColumn);
 
   filter.clear();
   column = numColumn;
 
   connect(ui->leFilter,SIGNAL(textChanged(QString)),this,SLOT(setTextFilter(QString )));
}
 
FilterWidget::~FilterWidget()
{
   qDebug()<<__FUNCTION__;
   delete ui;
}
 
void FilterWidget::closeEvent(QCloseEvent *event)
{
   qDebug()<<__FUNCTION__;
   Q_EMIT closeWidget();  
   QWidget::closeEvent(event);
}
 
void FilterWidget::setTextFilter(QString string)
{
   filter.clear();
   filter.append(string);
 
   Q_EMIT changeFilter(filter,column);
}
 

и  update фильтра для прокси

Код
C++ (Qt)
void DataBaseFilterModel::updateFilterColumn(QString string, int column)
{
   keyColumn = column;
   strFilter.clear();
   strFilter.append(string);    
   invalidateFilter();
}
 

Все работает замечательно.
Хочу подсвечивать текст при работе фильтра.
Добавляю делегата в проксю.

Код
C++ (Qt)
LineEditDelegate::LineEditDelegate(QObject *parent):
   QItemDelegate(parent)
{
}
 
LineEditDelegate::~LineEditDelegate()
{
}
 
QWidget *LineEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   if(index.column() == 1){
       QLineEdit *lineEdit = new QLineEdit(parent);
       return lineEdit;
   }
   return  QItemDelegate::createEditor(parent,option,index);
}
 
void LineEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
   if(index.column() == 1){
       QString string = index.model()->data(index,Qt::EditRole).toString();
       QLineEdit *le = static_cast<QLineEdit* >(editor);        
       le->setText(string);
   }
}
 
void LineEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
  if(index.column() == 1){
      QLineEdit *le = static_cast<QLineEdit* >(editor);
      QString str = le->text();
      model->setData(index,str,Qt::EditRole);
   }
}
 
void LineEditDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   editor->setGeometry(option.rect);
}
 
void LineEditDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   QString strFilter = ((DataBaseFilterModel*)(index.model()))->getStringFilter();
   const QModelIndex src = ((DataBaseFilterModel*)(index.model()))->mapToSource(index);
 
   qDebug()<<"paint";
 
   if(index.column() == 1 && !strFilter.isEmpty() && ((DataBaseFilterModel*)(index.model()))->filterAcceptsRow(src.row(),QModelIndex())){
       QFontMetrics fm(option.font);
       int h_cell = option.rect.height();
       int h_text = fm.boundingRect(strFilter).height();
       int w_text = fm.boundingRect(strFilter).width();
 
 
       painter->setPen(QPen("yellow"));
       painter->setBrush(QBrush("yellow"));
       painter->drawRect(option.rect.x(),option.rect.y() + ((h_cell-h_text)/2),w_text,h_text);
 
   }
   return QItemDelegate::paint(painter,option,index);
}
 
 

При изменении фильтра инфа фильтруется при этом окно фильтра активно!
Но текст не выделен при этом.
Как только окно с вьюшкой делаю активным, текст выделен. Такое впечатление, что делегат не перерисовывается.
Почему ???




Название: Re: QItemDelegate выделение текста надписи при фильтрации
Отправлено: GreatSnake от Сентябрь 06, 2016, 11:22
Попробуй вместо invalidateFilter() вызвать invalidate().


Название: Re: QItemDelegate выделение текста надписи при фильтрации
Отправлено: demaker от Сентябрь 06, 2016, 12:31
Попробуй вместо invalidateFilter() вызвать invalidate().

Спасибо заработало!!! А в чем фишка???  ???


Название: Re: QItemDelegate выделение текста надписи при фильтрации
Отправлено: GreatSnake от Сентябрь 06, 2016, 12:44
Спасибо заработало!!! А в чем фишка???  ???
По непонятной мне причине при invalidateFilter() модель не испускает ни одного сигнала.
Соответственно вьюха не обновлялась.
invalidate() испускает layoutChanged(), на который завязана вьюха.
Но надо иметь в виду, что вызов invalidate() может быть довольно-таки тяжелым.
Вполне возможно, что намного легче из updateFilterColumn() испустить свой сигнал типа filterColumnUpdated() и за-коннектить к нему TableView::viewport()->update().


Название: Re: QItemDelegate выделение текста надписи при фильтрации
Отправлено: demaker от Сентябрь 06, 2016, 13:02
Вполне возможно, что намного легче из updateFilterColumn() испустить свой сигнал типа filterColumnUpdated() и за-коннектить к нему TableView::viewport()->update().

Что не нашел такого метода viewport() в QTableView


Название: Re: QItemDelegate выделение текста надписи при фильтрации
Отправлено: GreatSnake от Сентябрь 06, 2016, 14:27
Код
C++ (Qt)
QWidget* QAbstractScrollArea::viewport() const


Название: Re: QItemDelegate выделение текста надписи при фильтрации
Отправлено: demaker от Сентябрь 06, 2016, 18:45
Код
C++ (Qt)
QWidget* QAbstractScrollArea::viewport() const


Спасибо работает и через сигнал-слот!