如何高亮显示QTreeView中的某些项(不继承)

如何高亮显示QTreeView中的某些项(不继承),qt,qtreeview,Qt,Qtreeview,我正在寻找一种在不重新实现QTreeView子类的情况下高亮显示QTreeView的行的方法 我看到过类似的问题: 但它们都使用委托。原因是我正在创建一个在widgets中搜索文本的工具,它可以浏览所有widgets并查找和突出显示其中的文本。因此,我不能使用委托 有什么可能的解决办法吗? 在上面画一个半透明的东西 下面是存储小部件的工具的代码以及在其中搜索文本的方法 class GUI_EXPORT QgsSearchHighlightOptionWidget : public Q

我正在寻找一种在不重新实现QTreeView子类的情况下高亮显示QTreeView的行的方法

我看到过类似的问题:

但它们都使用委托。原因是我正在创建一个在widgets中搜索文本的工具,它可以浏览所有widgets并查找和突出显示其中的文本。因此,我不能使用委托

有什么可能的解决办法吗? 在上面画一个半透明的东西


下面是存储小部件的工具的代码以及在其中搜索文本的方法

class GUI_EXPORT QgsSearchHighlightOptionWidget : public QObject
{
    Q_OBJECT
  public:

    /**
     * Constructor
     * \param widget the widget used to search text into
     */
    explicit QgsSearchHighlightOptionWidget( QWidget *widget = nullptr );

    /**
     * Returns if it valid: if the widget type is handled and if the widget is not still available
     */
    bool isValid() { return mWidget && mValid; }

    /**
     * search for a text pattern and highlight the widget if the text is found
     * \returns true if the text pattern is found
     */
    bool searchHighlight( const QString &searchText );

    /**
     *  reset the style to the original state
     */
    void reset();

    /**
     * return the widget
     */
    QWidget *widget() { return mWidget; }

    bool eventFilter( QObject *obj, QEvent *event ) override;

  private slots:
    void widgetDestroyed();

  private:
    QPointer< QWidget > mWidget;
    QString mStyleSheet;
    bool mValid = true;
    bool mChangedStyle = false;
    std::function < bool( QString )> mTextFound = []( QString searchText ) {Q_UNUSED( searchText ); return false;};
    bool mInstalledFilter = false;
};

QgsSearchHighlightOptionWidget::QgsSearchHighlightOptionWidget( QWidget *widget )
  : QObject( widget )
  , mWidget( widget )
{
  if ( qobject_cast<QLabel *>( widget ) )
  {
    mStyleSheet = QStringLiteral( "QLabel { background-color: yellow; color: blue;}" );
    mTextFound = [ = ]( QString searchText ) {return qobject_cast<QLabel *>( mWidget )->text().contains( searchText, Qt::CaseInsensitive );};
  }
  else if ( qobject_cast<QCheckBox *>( widget ) )
  {
    mStyleSheet = QStringLiteral( "QCheckBox { background-color: yellow; color: blue;}" );
    mTextFound = [ = ]( QString searchText ) {return qobject_cast<QCheckBox *>( mWidget )->text().contains( searchText, Qt::CaseInsensitive );};
  }
  else if ( qobject_cast<QAbstractButton *>( widget ) )
  {
    mStyleSheet = QStringLiteral( "QAbstractButton { background-color: yellow; color: blue;}" );
    mTextFound = [ = ]( QString searchText ) {return qobject_cast<QAbstractButton *>( mWidget )->text().contains( searchText, Qt::CaseInsensitive );};
  }
  else if ( qobject_cast<QGroupBox *>( widget ) )
  {
    mStyleSheet = QStringLiteral( "QGroupBox::title { background-color: yellow; color: blue;}" );
    mTextFound = [ = ]( QString searchText ) {return qobject_cast<QGroupBox *>( mWidget )->title().contains( searchText, Qt::CaseInsensitive );};
  }
  else if ( qobject_cast<QTreeView *>( widget ) )
  {
    // TODO - style individual matching items
    mTextFound = [ = ]( QString searchText )
    {
      QTreeView *tree = qobject_cast<QTreeView *>( mWidget );
      if ( !tree )
        return false;
      QModelIndexList hits = tree->model()->match( tree->model()->index( 0, 0 ), Qt::DisplayRole, searchText, 1, Qt::MatchContains | Qt::MatchRecursive );
      return !hits.isEmpty();
    };
  }
  else
  {
    mValid = false;
  }
  if ( mValid )
  {
    mStyleSheet.prepend( "/*!search!*/" ).append( "/*!search!*/" );
    QgsDebugMsgLevel( mStyleSheet, 4 );
    connect( mWidget, &QWidget::destroyed, this, &QgsSearchHighlightOptionWidget::widgetDestroyed );
  }
}

bool QgsSearchHighlightOptionWidget::searchHighlight( const QString &searchText )
{
  bool found = false;
  if ( !mWidget )
    return found;

  if ( !searchText.isEmpty() )
  {
    found = mTextFound( searchText );
  }

  if ( found && !mChangedStyle )
  {
    if ( !mWidget->isVisible() )
    {
      // show the widget to get initial stylesheet in case it's modified
      QgsDebugMsg( QString( "installing event filter on: %1 (%2)" )
                   .arg( mWidget->objectName() )
                   .arg( qobject_cast<QLabel *>( mWidget ) ? qobject_cast<QLabel *>( mWidget )->text() : QString() ) );
      mWidget->installEventFilter( this );
      mInstalledFilter = true;
    }
    else
    {
      mWidget->setStyleSheet( mWidget->styleSheet() + mStyleSheet );
      mChangedStyle = true;
    }
  }

  return found;
}

bool QgsSearchHighlightOptionWidget::eventFilter( QObject *obj, QEvent *event )
{
  if ( mInstalledFilter && event->type() == QEvent::Show && obj == mWidget )
  {
    mWidget->removeEventFilter( this );
    mInstalledFilter = false;
    // instead of catching the event and calling show again
    // it might be better to use a timer to change the style
    // after the widget is shown
#if 1
    mWidget->show();
    mWidget->setStyleSheet( mWidget->styleSheet() + mStyleSheet );
    return true;
#else
    QTimer::singleShot( 500, this, [ = ]
    {
      mWidget->setStyleSheet( mWidget->styleSheet() + mStyleSheet );
      mChangedStyle = true;
    } );
#endif
  }
  return QObject::eventFilter( obj, event );
}

void QgsSearchHighlightOptionWidget::reset()
{
  if ( mWidget && mValid )
  {
    if ( mChangedStyle )
    {
      QString ss = mWidget->styleSheet();
      ss.remove( mStyleSheet );
      mWidget->setStyleSheet( ss );
      mChangedStyle = false;
    }
    else if ( mInstalledFilter )
    {
      mWidget->removeEventFilter( this );
      mInstalledFilter = false;
    }
  }
}

void QgsSearchHighlightOptionWidget::widgetDestroyed()
{
  mWidget = nullptr;
  mValid = false;
}
class GUI\u导出QGSSearchHighlightOption小部件:公共QObject
{
Q_对象
公众:
/**
*建造师
*\param小部件用于搜索文本的小部件
*/
显式QgsSearchHighlightOptionWidget(QWidget*widget=nullptr);
/**
*返回它是否有效:小部件类型是否已处理,小部件是否仍然可用
*/
bool isValid(){return mWidget&&mValid;}
/**
*搜索文本模式,如果找到文本,则突出显示小部件
*\如果找到文本模式,则返回true
*/
bool searchHighlight(常量QString和searchText);
/**
*将样式重置为原始状态
*/
无效重置();
/**
*返回小部件
*/
QWidget*widget(){return mWidget;}
布尔事件过滤器(QObject*obj,QEvent*event)覆盖;
专用插槽:
void-widgetdemployed();
私人:
QPointermWidget;
QString-mStyleSheet;
bool mValid=真;
bool-mChangedStyle=false;
std::functionmtextfind=[](qstringsearchtext){Q_UNUSED(searchText);返回false;};
bool mInstalledFilter=false;
};
QgsSearchHighlightOptionWidget::QgsSearchHighlightOptionWidget(QWidget*widget)
:QObject(小部件)
,mWidget(小部件)
{
if(qobject_cast(小部件))
{
mStyleSheet=QStringLiteral(“QLabel{背景色:黄色;颜色:蓝色;}”);
mTextFound=[=](QString searchText){return qobject_cast(mWidget)->text().contains(searchText,Qt::case不敏感);};
}
else if(qobject_cast(小部件))
{
mStyleSheet=QStringLiteral(“QCheckBox{背景色:黄色;颜色:蓝色;}”);
mTextFound=[=](QString searchText){return qobject_cast(mWidget)->text().contains(searchText,Qt::case不敏感);};
}
else if(qobject_cast(小部件))
{
mStyleSheet=QStringLiteral(“QAbstractButton{背景色:黄色;颜色:蓝色;}”);
mTextFound=[=](QString searchText){return qobject_cast(mWidget)->text().contains(searchText,Qt::case不敏感);};
}
else if(qobject_cast(小部件))
{
mStyleSheet=QStringLiteral(“QGroupBox::title{背景色:黄色;颜色:蓝色;}”);
mTextFound=[=](QString searchText){return qobject_cast(mWidget)->title().contains(searchText,Qt::case不敏感);};
}
else if(qobject_cast(小部件))
{
//TODO样式的单个匹配项
mTextFound=[=](QString搜索文本)
{
QTreeView*tree=qobject_cast(mWidget);
如果(!树)
返回false;
QModelIndexList hits=tree->model()->match(tree->model()->index(0,0),Qt::DisplayRole,searchText,1,Qt::MatchContains | Qt::MatchRecursive);
return!hits.isEmpty();
};
}
其他的
{
mValid=false;
}
if(mValid)
{
mStyleSheet.prepend(“/*!search!*/”)。append(“/*!search!*/”);
QgsDebugMsgLevel(mStyleSheet,4);
连接(mWidget、&QWidget::destrocted、this、&QgsSearchHighlightOptionWidget::widget destrocted);
}
}
bool QgsSearchHighlightOptionWidget::searchHighlight(常量QString和searchText)
{
bool-found=false;
如果(!mWidget)
发现退货;
如果(!searchText.isEmpty())
{
found=mTextFound(searchText);
}
如果(找到&!mChangedStyle)
{
如果(!mWidget->isVisible())
{
//显示小部件以获取初始样式表,以防修改
QgsDebugMsg(QString(“在%1(%2)上安装事件筛选器”)
.arg(mWidget->objectName())
.arg(qobject_cast(mWidget)→qobject_cast(mWidget)->text():QString());
mWidget->installEventFilter(此);
mInstalledFilter=true;
}
其他的
{
mWidget->setStyleSheet(mWidget->styleSheet()+mStyleSheet);
mChangedStyle=true;
}
}
发现退货;
}
bool QgsSearchHighlightOptionWidget::eventFilter(QObject*obj,QEvent*event)
{
if(minInstalledFilter&&event->type()==QEvent::Show&&obj==mWidget)
{
mWidget->removeEventFilter(此);
mInstalledFilter=false;
//而不是捕捉事件并再次调用show
//最好使用计时器来更改样式
//显示小部件后
#如果1
mWidget->show();
mWidget->setStyleSheet(mWidget->styleSheet()+mStyleSheet);
返回true;
#否则
QTimer::singleShot(500,这个,[=]
{
mWidget->setStyleSheet(mWidget->styleSheet()+mStyleSheet);
mChangedStyle=true;
} );
#恩迪夫
}
返回QObject::eventFilter(对象,事件);
}
void QgsSearchHighlightOptionWidget::reset()
{
if(mWidget&mValid)
{
if(mChangedStyle)
{
QString ss=mWidget->styleSheet();
ss.移除(mStyleSheet);
mWidget->setStyleSheet(ss);
mChangedStyle=false;
}
else if(MinInstalledFilter)
{
mWidget->removeEventFilter(此);
mInstalledFilter=false;
}
}
}
void QgsSearchHighlightOptionWidget::widgetDestroyed()
{
mWidget=nullptr;
mValid=false;
}
下面是从对话框中实际注册小部件的代码:

void QgsOptionsDialogBase::registerTextSearchWidgets()
{
  mRegisteredSearchWidgets.clear();

  for ( int i = 0; i < mOptStackedWidget->count(); i++ )
  {
    Q_FOREACH ( QWidget *w, mOptStackedWidget->widget( i )->findChildren<QWidget *>() )
    {
      QgsSearchHighlightOptionWidget *shw = new QgsSearchHighlightOptionWidget( w );
      if ( shw->isValid() )
      {
        QgsDebugMsgLevel( QString( "Registering: %1" ).arg( w->objectName() ), 4 );
        mRegisteredSearchWidgets.append( qMakePair( shw, i ) );
      }
      else
      {
        delete shw;
      }
    }
  }
}
void QGSoptionDialogBase::registerTextSearchWidgets()
{
mRegisteredSearchWidgets.clear();
对于(int i=0;icount();i++)
{
Q_FOREACH(QWidget*w,mOptStackedWidget->widget(