【问题标题】:get the Widgets' tree of an application获取应用程序的小部件树
【发布时间】:2014-09-28 07:23:37
【问题描述】:

众所周知,Qt 使用"parent-child relationship" 将小部件链接在一起。为了维护(C++)Qt5 应用程序,我正在寻找能够以某种方式描述这些关系的工具,例如:

  QMainApplication
  |
  \----->QMainWindow
         |
         \----->QSplitter(as CentralWidget)
                |
                \--->QTextEdit
                \--->QTextEdit

它可能是一个函数,可以从带有QApplication作为参数的代码中启动;它可能是一个能够分析代码的外部工具。

有这样的功能/工具吗?

【问题讨论】:

    标签: c++ qt widget qwidget


    【解决方案1】:

    解决办法很少:

    Qt Designer 中有一个小部件可以做类似的事情。

    但是你可以使用这个类来查看关系:

    ObjectTreeModel.h

    #ifndef OBJECTTREEMODEL_H
    #define OBJECTTREEMODEL_H
    
    #include <QAbstractItemModel>
    
    class ObjectTreeModel : public QAbstractItemModel
    {
        Q_OBJECT
    public:
        ObjectTreeModel( QObject *root, QObject *parent = 0 )
        {
            m_root = root;
        }
    
        QVariant data( const QModelIndex &index, int role ) const;
        QVariant headerData( int section, Qt::Orientation orientation,
        int role = Qt::DisplayRole ) const;
        int rowCount( const QModelIndex &parent = QModelIndex() ) const;
        int columnCount( const QModelIndex &parent = QModelIndex() ) const;
        QModelIndex index( int row, int column,
        const QModelIndex &parent = QModelIndex() ) const;
        QModelIndex parent( const QModelIndex &index ) const;
    private:
        QObject *m_root;
    };
    
    #endif // OBJECTTREEMODEL_H
    

    *.cpp

    #include "objecttreemodel.h"
    
    
    
    QVariant ObjectTreeModel::headerData(int section, Qt::Orientation orientation, int role ) const
        {
             if( role != Qt::DisplayRole || orientation != Qt::Horizontal )
                return QVariant();
             switch( section )
            {
                case 0:
                    return QString( "Object" );
                case 1:
                    return QString( "Class" );
                default:
                    return QVariant();
            }
        }
    
    QModelIndex ObjectTreeModel::index(int row, int column,const QModelIndex &parent ) const
    {
        QObject *parentObject;
        if( !parent.isValid() )
            parentObject = m_root;
        else
            parentObject = static_cast<QObject*>( parent.internalPointer() );
        if( row >= 0 && row < parentObject->children().count() )
            return createIndex( row, column, parentObject->children().at( row ) );
        else
            return QModelIndex();
    }
    
    int ObjectTreeModel::rowCount(const QModelIndex &parent ) const
    {
        QObject *parentObject;
        if( !parent.isValid() )
            parentObject = m_root;
        else
            parentObject = static_cast<QObject*>( parent.internalPointer() );
        return parentObject->children().count();
    }
    int ObjectTreeModel::columnCount(const QModelIndex &parent ) const
    {
        return 2;
    } 
    
    QVariant ObjectTreeModel::data( const QModelIndex &index, int role) const
    {
        if( !index.isValid() )
            return QVariant();
        if( role == Qt::DisplayRole )
        {
        switch( index.column() )
        {
            case 0:
                return static_cast<QObject*>( index.internalPointer() )->objectName();
            case 1:
                return static_cast<QObject*>( index.internalPointer() )->metaObject()->className();
            default:
                break;
        }
        }
    return QVariant();
    }
    
    QModelIndex ObjectTreeModel::parent(const QModelIndex &index) const
    {
        if( !index.isValid() )
            return QModelIndex();
        QObject *indexObject = static_cast<QObject*>( index.internalPointer() );
        QObject *parentObject = indexObject->parent();
        if( parentObject == m_root )
            return QModelIndex();
        QObject *grandParentObject = parentObject->parent();
        return createIndex( grandParentObject->children().indexOf( parentObject ),0, parentObject );
    }
    

    用法(在 main.cpp 中):

    #include "objecttreemodel.h"
    //...
    MainWindow w;
    w.show();
    ObjectTreeModel *model = new ObjectTreeModel(&w);
    QTreeView tree;
    tree.setModel(model);
    tree.show();
    

    结果:

    【讨论】:

    • 非常有趣:感谢您分享您的代码!
    • 如果你要添加一个事件过滤器来控制子对象的创建和删除,你的解决方案会很棒:)
    猜你喜欢
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 2011-05-10
    • 2018-03-21
    • 2023-02-14
    • 1970-01-01
    相关资源
    最近更新 更多