Why is only the heading displayed in a QTreeView
, but not the item (with string-data "Item1") itself?
The model is set correctly via setModel()
on the QTreeView
and no other properties are set.
I used QT 6.5.2 and C++20.
Minimal, compilable example:
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(DemoModel VERSION 1.0
DESCRIPTION "DemoModel"
LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
add_executable(DemoModel WIN32
demo_model.h)
if ( MSVC )
set_target_properties(DemoModel PROPERTIES LINK_FLAGS "/ignore:4099")
target_compile_options(DemoModel PRIVATE "/WX")
endif()
set_target_properties(DemoModel PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
)
set_target_properties(DemoModel PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
include(CheckIPOSupported)
check_ipo_supported(RESULT result)
if(result)
set_target_properties(DemoModel PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
target_link_libraries(DemoModel PRIVATE Qt6::Core)
target_link_libraries(DemoModel PRIVATE Qt6::Gui)
target_link_libraries(DemoModel PRIVATE Qt6::Widgets)
target_include_directories(DemoModel PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_sources(DemoModel PRIVATE
#Souces
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/demo_model.h"
)
demo_model.h
#pragma once
#include <QAbstractItemModel>
class DemoModel : public QAbstractItemModel
{
Q_OBJECT
public:
DemoModel( QObject *parent = nullptr );
QVariant data(const QModelIndex &index, int role) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
};
main.cpp
#include <QApplication>
#include <QTreeView>
#include <QHBoxLayout>
#include "demo_model.h"
DemoModel::DemoModel( QObject *parent ) : QAbstractItemModel( parent ) {}
Qt::ItemFlags DemoModel::flags( const QModelIndex &index ) const
{
if ( !index.isValid() )
return Qt::NoItemFlags;
return QAbstractItemModel::flags( index );
}
QVariant DemoModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() )
return QVariant();
return "Item1";
}
QVariant DemoModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole )
return "Items";
return QVariant();
}
QModelIndex DemoModel::index( int row, int column, const QModelIndex &parent ) const
{
if ( !hasIndex(row, column, parent ) )
return QModelIndex();
if ( !parent.isValid() )
{
if ( row == 0 && column == 0 )
return createIndex( row, column, nullptr );
}
return QModelIndex();
}
QModelIndex DemoModel::parent( const QModelIndex &index ) const
{
return QModelIndex();
}
int DemoModel::rowCount( const QModelIndex &parent ) const
{
if ( !parent.isValid() )
return 1;
return 0;
}
int DemoModel::columnCount( const QModelIndex &parent ) const
{
return 1;
}
class MainWindow : public QWidget
{
public:
explicit MainWindow( QWidget *parent = nullptr ) : QWidget( parent )
{
auto *demoModel = new DemoModel();
auto *demoView = new QTreeView();
demoView->setModel( demoModel );
auto layout = new QHBoxLayout;
layout->addWidget( demoView );
setLayout( layout );
setWindowTitle( tr( "DemoModel" ) );
}
};
auto main( int argc, char *argv[] ) -> int
{
QApplication app( argc, argv );
app.setAttribute( Qt::AA_DontCreateNativeWidgetSiblings );
MainWindow window;
window.show();
return app.exec();
}
It seems that it is not a good idea to return "Item1" in the data method regardless of the role. If you now restrict the return of the string to the display role, everything is displayed correctly.
QVariant DemoModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() )
return QVariant();
if ( role == Qt::DisplayRole )
return "Item1";
return QVariant();
}