이 페이지에서

QRangeModel Class

QRangeModel은 모든 C++ 범위에 대해 ` QAbstractItemModel `를 구현합니다. 더 보기...

헤더: #include <QRangeModel>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
다음부터: Qt 6.10
상속받음: QAbstractItemModel

참고: 이 클래스의 모든 함수는 재진입 가능합니다.

공개 유형

(since 6.11) struct ItemAccess
(since 6.10) struct RowOptions
(since 6.11) enum class AutoConnectPolicy { None, Full, OnRead }
(since 6.12) enum class DropOperation { DontDrop, Automatic, OverwriteAndIgnore, OverwriteAndExtend, InsertAsSiblings, InsertAsChildren }
enum class RowCategory { Default, MultiRoleItem }

속성

공개 함수

QRangeModel(Range &&range, QObject *parent = nullptr)
QRangeModel(Range &&range, Protocol &&protocol, QObject *parent = nullptr)
virtual ~QRangeModel() override
QRangeModel::AutoConnectPolicy autoConnectPolicy() const
void resetRoleNames()
void resetSortCollator()
void resetSortRole()
void resetSupportedDragActions()
void resetSupportedDropActions()
void setAutoConnectPolicy(QRangeModel::AutoConnectPolicy policy)
void setRoleNames(const QHash<int, QByteArray> &names)
void setSortCollator(const QCollator &collator)
void setSortRole(int role)
void setSupportedDragActions(Qt::DropActions actions)
void setSupportedDropActions(Qt::DropActions actions)
QCollator sortCollator() const
int sortRole() const

재구현된 공용 함수

virtual QModelIndex buddy(const QModelIndex &index) const override
virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override
virtual bool canFetchMore(const QModelIndex &parent) const override
virtual bool clearItemData(const QModelIndex &index) override
virtual int columnCount(const QModelIndex &parent = {}) const override
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
virtual void fetchMore(const QModelIndex &parent) override
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const override
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override
virtual bool insertColumns(int column, int count, const QModelIndex &parent = {}) override
virtual bool insertRows(int row, int count, const QModelIndex &parent = {}) override
virtual QMap<int, QVariant> itemData(const QModelIndex &index) const override
virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const override
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override
virtual QStringList mimeTypes() const override
virtual bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationColumn) override
virtual bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationRow) override
virtual void multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const override
virtual QModelIndex parent(const QModelIndex &child) const override
virtual bool removeColumns(int column, int count, const QModelIndex &parent = {}) override
virtual bool removeRows(int row, int count, const QModelIndex &parent = {}) override
virtual QHash<int, QByteArray> roleNames() const override
virtual int rowCount(const QModelIndex &parent = {}) const override
virtual bool setData(const QModelIndex &index, const QVariant &data, int role = Qt::EditRole) override
virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &data, int role = Qt::EditRole) override
virtual bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &data) override
virtual QModelIndex sibling(int row, int column, const QModelIndex &index) const override
virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override
virtual QSize span(const QModelIndex &index) const override
virtual Qt::DropActions supportedDragActions() const override
virtual Qt::DropActions supportedDropActions() const override

신호

void autoConnectPolicyChanged(QRangeModel::AutoConnectPolicy policy)
void roleNamesChanged()
void sortCollatorChanged(const QCollator &collator)
void sortRoleChanged(int role)
void supportedDragActionsChanged(Qt::DropActions actions)
void supportedDropActionsChanged(Qt::DropActions actions)

재구현된 보호 함수

virtual bool event(QEvent *event) override
virtual bool eventFilter(QObject *object, QEvent *event) override

보호된 슬롯

virtual void resetInternalData() override

상세 설명

QRangeModel은 순차적으로 반복 가능한 모든 C++ 유형의 데이터를 Qt의 모델/뷰 프레임워크에서 사용할 수 있게 해줍니다. 이를 통해 Qt Widgets 및 Qt Quick 항목 뷰에서 기존 데이터 구조를 쉽게 표시할 수 있으며, 애플리케이션 사용자가 그래픽 사용자 인터페이스를 통해 데이터를 조작할 수 있게 됩니다.

QRangeModel을 사용하려면 C++ 범위(range)로 인스턴스를 생성하고, 하나 이상의 뷰의 모델로 설정하십시오:

std::array<int, 5> numbers = {1, 2, 3, 4, 5};
QRangeModel model(numbers);
listView.setModel(&model);

모델 생성

레인지는 std::begin 및 std::end 표준 메서드가 구현되어 있고, 반환되는 이터레이터 유형이 std::forward_iterator 를 만족하는 모든 C++ 유형일 수 있습니다. std::size 를 사용할 수 있고 이터레이터가 std::random_access_iterator 를 만족하는 경우, 특정 모델 연산의 성능이 향상됩니다.

모델을 생성할 때는 범위를 반드시 제공해야 하며, 이는 값, 참조 래퍼 또는 포인터로 제공할 수 있습니다. 모델이 어떻게 생성되었는지에 따라 모델 API를 통한 변경 사항이 원본 데이터를 수정할지 여부가 결정됩니다. QRangeModelAdapter 를 사용하면 모델을 암시적으로 생성하는 동시에, 범위로 모델에 직접적이고 유형 안전하며 편리한 방식으로 접근할 수 있습니다.

값으로 생성된 경우, 모델은 범위의 복사본을 생성하며, setData()이나 insertRows()과 같이 모델을 수정하는 QAbstractItemModel API는 원본 범위에 아무런 영향을 미치지 않습니다.

QRangeModel model(numbers);

데이터에 가해진 변경 사항은 dataChanged() 와 같이 모델에서 발산되는 신호에 연결하여 모니터링할 수 있습니다.

모델의 수정이 원본 범위에 반영되도록 하려면, 포인터를 통해 범위를 지정하거나:

QRangeModel model(&numbers);

또는 참조 래퍼를 통해 범위(range)를 제공하십시오:

QRangeModel model(std::ref(numbers));

이 경우, 모델을 수정하는 QAbstractItemModel API는 범위도 함께 수정합니다. insertRows() 또는 removeColumns()과 같이 범위의 구조를 수정하는 메서드는 데이터를 설정하거나 지우기 위해 변형 이터레이터를 역참조하는 것 외에도 표준 C++ 컨테이너 API resize(), insert(), erase() 를 사용합니다.

참고: 모델이 생성되어 뷰로 전달된후에는 , 모델이 작동하는 범위를 더 이상 직접 수정해서는 안 됩니다. 모델에 대한 뷰에는 변경 사항이 반영되지 않을 것이며, 구조적 변경은 모델이 관리하는 ` QPersistentModelIndex ` 인스턴스를 손상시킬 가능성이 높습니다. 모델을 최신 상태로 유지하면서 기본 범위를 안전하게 처리하려면 ` QRangeModelAdapter `를 사용하십시오.

호출자는 범위의 수명이 모델의 수명보다 길도록 보장해야 합니다.

스마트 포인터를 사용하여 모든 클라이언트가 범위를 더 이상 사용하지 않을 때에만 범위가 삭제되도록 해야 합니다.

auto shared_numbers = std::make_shared<std::vector<int>>(numbers);
QRangeModel model(shared_numbers);

QRangeModel은 공유 포인터와 고유 포인터를 모두 지원합니다.

읽기 전용 또는 변경 가능

상수 객체인 범위, 액세스가 항상 상수 값을 반환하는 범위, 또는 필요한 컨테이너 API를 사용할 수 없는 범위의 경우, QRangeModel은 아무 작업도 수행하지 않고 ` false`를 반환하는 쓰기 액세스 API를 구현합니다. ` std::array`를 사용하는 예제에서, C++ 배열의 항목 수는 고정되어 있으므로 모델은 행을 추가하거나 제거할 수 없습니다. 하지만 setData()을 사용하여 값을 변경할 수 있으며, 사용자는 목록 보기에서 값 편집을 시작할 수 있습니다. 배열을 const로 설정하면 값도 읽기 전용이 됩니다.

const std::array<int, 5> numbers = {1, 2, 3, 4, 5};

다음 예제와 같이 요소 유형이 const인 경우에도 값은 읽기 전용이 됩니다.

std::array<const int, 5> numbers = {1, 2, 3, 4, 5};

std::vector 를 사용하는 위의 예제에서는 모델이 행을 추가하거나 제거할 수 있으며, 데이터를 변경할 수도 있습니다. 범위를 상수 참조로 전달하면 모델이 읽기 전용이 됩니다.

QRangeModel model(std::cref(numbers));

참고: 범위 내의 값이 const인경우 , QAbstractItemModel API를 통해 열과 행을 제거하거나 삽입할 수도 없습니다. 더 세밀한 제어를 위해서는 the C++ tuple protocol 를 구현하십시오.

행과 열

범위 내의 요소들은 모델의 행으로 해석됩니다. 이러한 행 요소의 유형에 따라 QRangeModel은 범위를 리스트, 테이블 또는 트리 형태로 노출합니다.

행 요소가 단순 값인 경우, 범위는 리스트로 표현됩니다.

QList<int> numbers = {1, 2, 3, 4, 5};
QRangeModel model(numbers); // columnCount() == 1
QListView listView;
listView.setModel(&model);

행 요소의 유형이 벡터, 리스트 또는 배열과 같은 반복 가능한 범위인 경우, 범위는 테이블로 표현됩니다.

std::vector<std::vector<int>> gridOfNumbers = {
    {1, 2, 3, 4, 5},
    {6, 7, 8, 9, 10},
    {11, 12, 13, 14, 15},
};
QRangeModel model(&gridOfNumbers); // columnCount() == 5
QTableView tableView;
tableView.setModel(&model);

행 유형이 표준 C++ 컨테이너 API resize(), insert(), erase() 를 제공하는 경우, insertColumns() 및 removeColumns()을 통해 열을 추가하거나 제거할 수 있습니다. 모든 행은 동일한 수의 열을 가져야 합니다.

행으로 사용되는 구조체 및 가젯

행 유형이 the C++ tuple protocol 를 구현하는 경우, 해당 범위는 고정된 열 수를 가진 테이블로 표현됩니다.

using TableRow = std::tuple<int, QString>;
QList<TableRow> numberNames = {
    {1, "one"},
    {2, "two"},
    {3, "three"}
};
QRangeModel model(&numberNames); // columnCount() == 2
QTableView tableView;
tableView.setModel(&model);

C++ 유형에 대해 튜플 프로토콜을 구현하는 것보다 더 쉽고 유연한 대안은 Qt의 메타 객체 시스템을 사용하여 속성을 가진 유형을 선언하는 것입니다. 이는 gadget 로 선언된 값 유형이거나, QObject 의 하위 클래스일 수 있습니다.

class Book
{
    Q_GADGET
    Q_PROPERTY(QString title READ title)
    Q_PROPERTY(QString author READ author)
    Q_PROPERTY(QString summary MEMBER m_summary)
    Q_PROPERTY(int rating READ rating WRITE setRating)
public:
    Book(const QString &title, const QString &author);

    // C++ rule of 0: destructor, as well as copy/move operations
    // provided by the compiler.

    // read-only properties
    QString title() const { return m_title; }
    QString author() const { return m_author; }

    // read/writable property with input validation
    int rating() const { return m_rating; }
    void setRating(int rating)
    {
        m_rating = qBound(0, rating, 5);
    }

private:
    QString m_title;
    QString m_author;
    QString m_summary;
    int m_rating = 0;
};

QObject 의 하위 클래스를 사용하면 속성을 바인딩하거나 변경 알림 신호를 설정할 수 있습니다. 하지만 항목에 QObject 인스턴스를 사용하면 메모리 오버헤드가 상당히 큽니다.

Qt 가젯이나 객체를 사용하는 것이 튜플 프로토콜을 구현하는 것보다 더 편리하고 유연할 수 있습니다. 또한 이러한 유형은 QML 내부에서도 직접 접근할 수 있습니다. 하지만 속성 시스템을 통한 접근에는 약간의 런타임 오버헤드가 따릅니다. 성능이 중요한 모델의 경우, 컴파일 시점에 접근 코드를 생성하기 위해 튜플 프로토콜을 구현하는 것을 고려해 보십시오.

다중 역할 항목

data(), setData(), clearItemData() 등의 구현체가 조작하는 항목의 유형은 위의 gridOfNumbers 예제와 같이 모델 전체에 걸쳐 동일할 수 있습니다. 하지만 numberNames 사례에서와 같이, 범위(range) 내의 각 열마다 서로 다른 항목 유형을 가질 수도 있습니다.

기본적으로 이 값은 Qt::DisplayRole 및 Qt::EditRole 역할에 사용됩니다. 대부분의 뷰는 이 값이 convertible to and from a QString 이기를 기대합니다(하지만 사용자 정의 델리게이트를 사용하면 더 큰 유연성을 확보할 수 있습니다).

여러 역할을 가진 연관 컨테이너

항목이 키 유형으로 int, Qt::ItemDataRole 또는 QString 를 사용하고, 매핑된 유형으로 QVariant 를 사용하는 연관 컨테이너인 경우, QRangeModel은 해당 컨테이너를 여러 역할에 대한 데이터 저장소로 해석합니다. data() 및 setData() 함수는 컨테이너 내의 매핑된 값을 반환하거나 수정하며, setItemData()는 제공된 모든 값을 수정하고, itemData()는 저장된 모든 값을 반환하며, clearItemData()는 컨테이너 전체를 비웁니다.

using ColorEntry = QMap<Qt::ItemDataRole, QVariant>;

const QStringList colorNames = QColor::colorNames();
QList<ColorEntry> colors;
colors.reserve(colorNames.size());
for (const QString &name : colorNames) {
    const QColor color = QColor::fromString(name);
    colors << ColorEntry{{Qt::DisplayRole, name},
                        {Qt::DecorationRole, color},
                        {Qt::ToolTipRole, color.name()}};
}
QRangeModel colorModel(colors);
QListView list;
list.setModel(&colorModel);

키로 사용하기에 가장 효율적인 데이터 유형은 Qt::ItemDataRole 또는 int 입니다. int 를 사용할 경우, itemData()는 컨테이너를 있는 그대로 반환하므로 데이터의 복사본을 생성할 필요가 없습니다.

다중 역할 항목으로서의 가젯 및 객체

가젯과 QObject 유형도 다중 역할 항목으로 표현될 수 있습니다. 이러한 항목의 속성은 name of a role 가 일치하는 역할에 사용됩니다. 모든 항목이 동일한 유형의 가젯이나 QObject 를 포함하는 경우, QRangeModel의 roleNames() 구현은 해당 유형의 속성 목록을 반환합니다.

class ColorEntry
{
    Q_GADGET
    Q_PROPERTY(QString display READ colorName)
    Q_PROPERTY(QColor decoration READ decoration)
    Q_PROPERTY(QString toolTip READ toolTip)
public:
    ColorEntry(const QString &color = {})
        : m_colorName(color)
    {}

    QString colorName() const
    {
        return m_colorName;
    }
    QColor decoration() const
    {
        return QColor::fromString(m_colorName);
    }
    QString toolTip() const
    {
        return QColor::fromString(m_colorName).name();
    }

private:
    QString m_colorName;
};

테이블에서 사용될 때, 이는 가젯의 기본 표현 방식입니다:

QList<QList<ColorEntry>> colorTable;

// ...

QRangeModel colorModel(colorTable);
QTableView table;
table.setModel(&colorModel);

그러나 목록에서 사용될 경우, 이러한 유형은 기본적으로 다중 열 행으로 표현되며, 각 속성은 별도의 열로 표시됩니다. 가젯을 목록에서 다중 역할 항목으로 표현하도록 강제하려면, QRoleModel::RowOptions를 특화하여 static constexpr auto rowCategory 멤버 변수를 MultiRoleItem 로 설정함으로써 해당 가젯을 다중 역할 유형으로 선언하십시오.

class ColorEntry
{
    Q_GADGET
    Q_PROPERTY(QString display READ colorName)
    Q_PROPERTY(QColor decoration READ decoration)
    Q_PROPERTY(QString toolTip READ toolTip)
public:
    ...
};
template <>
struct QRangeModel::RowOptions<ColorEntry>
{
    static constexpr auto rowCategory = QRangeModel::RowCategory::MultiRoleItem;
};

또한 이러한 유형을 단일 요소 튜플로 감싸서 목록을 단일 열로 구성된 테이블로 변환할 수도 있습니다:

const QStringList colorNames = QColor::colorNames();
QList<std::tuple<ColorEntry>> colors;

// ...

QRangeModel colorModel(colors);
QListView list;
list.setModel(&colorModel);

이 경우, 리스트 데이터의 요소에 직접 접근하려면 std::get 을 사용해야 한다는 점에 유의하십시오:

ColorEntry firstEntry = std::get<0>(colors.at(0));

또는 구조화된 바인딩을 사용할 수도 있습니다:

auto [firstEntry] = colors.at(0);

값 또는 포인터로 표현된 행

지금까지의 예제에서는 항상 값을 포함하는 범위를 가진 QRangeModel을 사용해 왔습니다. QRangeModel은 스마트 포인터를 포함하여 포인터를 포함하는 범위에서도 작동할 수 있습니다. 이를 통해 QRangeModel은 QObject 의 하위 클래스와 같은 다형성 유형의 범위에서도 작동할 수 있습니다.

class Entry : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString display READ display WRITE setDisplay NOTIFY displayChanged)
    Q_PROPERTY(QIcon decoration READ decoration WRITE setDecoration NOTIFY decorationChanged)
    Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip NOTIFY toolTipChanged)

public:
    Entry() = default;

    QString display() const
    {
        return m_display;
    }

    void setDisplay(const QString &display)
    {
        if (m_display == display)
            return;
        m_display = display;
        emit displayChanged(m_display);
    }

signals:
    void displayChanged(const QString &);
    ...
};
std::vector<std::shared_ptr<Entry>> entries = {
    ...
};
QRangeModel model(std::ref(entries));
QListView listView;
listView.setModel(&model);

값의 경우와 마찬가지로, 행의 유형에 따라 범위가 리스트, 테이블 또는 트리로 표현되는지 결정됩니다. QObject인 행은 QRangeModel::RowOptions 템플릿이 해당 유형을 다중 역할 항목으로 선언하도록 특화되지 않은 한, 각 속성을 열로 표시합니다.

template <>
struct QRangeModel::RowOptions<Entry>
{
    static constexpr auto rowCategory = QRangeModel::RowCategory::MultiRoleItem;
};
std::vector<std::shared_ptr<Entry>> entries = {
    std::make_shared<Entry>(),
    ...
};

QRangeModel model(std::ref(entries));

참고: 범위에 원시 포인터가 포함되어 있는경우 , 해당 범위의 포인터 또는 참조 래퍼를 사용하여 QRangeModel을 생성해야 합니다. 그렇지 않으면 데이터의 소유권이 모호해지며, 범위의 복사본이 여전히 동일한 실제 행 데이터를 조작하게 되어 예상치 못한 부작용이 발생할 수 있습니다.

QRangeModel의 서브클래스 생성

QRangeModel을 상속하면 범위의 데이터 유형과 구조를 고려한 편리한 API를 추가할 수 있습니다.

class NumbersModel : public QRangeModel
{
    std::vector<int> m_numbers;

public:
    NumbersModel(const std::vector<int> &numbers)
        : QRangeModel(std::ref(m_numbers))
        , m_numbers(numbers)
    {
    }

이 경우, 레인지를 비공개 멤버로 추가하고, 해당 멤버에 대한 참조 래퍼나 포인터를 사용하여 QRangeModel 생성자를 호출하십시오. 이렇게 하면 데이터가 적절하게 캡슐화되고 직접 액세스가 방지됩니다.

    void setNumber(int idx, int number)
    {
        setData(index(idx, 0), QVariant::fromValue(number));
    }

    int number(int idx) const
    {
        return m_numbers.at(idx);
    }
};

QAbstractItemModel API를 사용하여 레인지를 수정하는 모든 작업을 수행하고, 데이터에 대한 유형 안전한 액세스를 제공하는 멤버 함수를 추가하십시오. 읽기 전용 액세스의 경우 데이터 구조를 직접 조작할 수 있습니다.

데이터 트리

QRangeModel은 데이터 구조를 트리 모델로 표현할 수 있습니다. 이러한 트리 데이터 구조는 동형적(homomorphic)이어야 합니다. 즉, 트리의 모든 레벨에서 자식 행 목록은 트리 자체와 정확히 동일한 표현 방식을 사용해야 합니다. 또한, 행 유형은 정적 크기를 가져야 합니다. 즉, 가젯(gadget)이나 QObject 유형이거나, the C++ tuple protocol 를 구현하는 유형이어야 합니다.

이러한 데이터를 트리 형태로 표현하기 위해, QRangeModel은 데이터 구조를 탐색할 수 있어야 합니다. 즉, 주어진 행에 대해 모델은 부모 행과 선택적인 자식 행 범위를 검색할 수 있어야 합니다. 이러한 탐색 함수는 행 유형을 통해 암시적으로 제공되거나, 명시적인 프로토콜 유형을 통해 제공될 수 있습니다.

암시적 트리 탐색 프로토콜

class TreeRow;

using Tree = std::vector<TreeRow>;

트리 자체는 ` TreeRow ` 값의 벡터입니다. 행에 항목의 값을 사용할지 포인터를 사용할지에 대한 고려 사항은 Tree Rows as pointers or values 를 참조하십시오.

class TreeRow
{
    Q_GADGET
    // properties

    TreeRow *m_parent;
    std::optional<Tree> m_children;

public:
    TreeRow() = default;

    // rule of 0: copy, move, and destructor implicitly defaulted

행 클래스는 앞서 설명한 고정 크기 유형(튜플 프로토콜을 구현하는 유형, 가젯 또는 QObject) 중 어느 것이나 될 수 있습니다. 이 예제에서는 가젯을 사용합니다.

각 행 항목은 부모 행에 대한 포인터와, 선택적으로 자식 행의 범위를 유지해야 합니다. 이 범위는 트리 자체에 사용되는 범위 구조와 동일해야 합니다.

행 유형을 기본 생성 가능하게 만드는 것은 선택 사항이며, 이를 통해 모델이 예를 들어 ` insertRow()` 또는 ` moveRows()` 구현에서 새로운 행 데이터 요소를 생성할 수 있게 됩니다.

    // tree traversal protocol implementation
    const TreeRow *parentRow() const { return m_parent; }
    const std::optional<Tree> &childRows() const { return m_children; }

그런 다음 트리 탐색 프로토콜을 행 데이터 유형의 멤버 함수로 구현할 수 있습니다. const parentRow() 함수는 행 항목에 대한 포인터를 반환해야 하며, childRows() 함수는 선택적 자식 범위를 담을 수 있는 const std::optional 에 대한 참조를 반환해야 합니다.

이 두 함수만으로도 모델이 트리를 읽기 전용 데이터 구조로 탐색하는 데 충분합니다. 사용자가 뷰에서 데이터를 편집할 수 있도록 하고, 모델이 insertRows(), removeRows(), moveRows()와 같은 변형 가능한 모델 API를 구현할 수 있도록 하려면, 쓰기 액세스를 위한 추가 함수를 구현해야 합니다:

    void setParentRow(TreeRow *parent) { m_parent = parent; }
    std::optional<Tree> &childRows() { return m_children; }

모델은 setParentRow() 함수와 가변형 childRows() 오버로드를 호출하여 기존 트리 분기에 행을 이동하거나 삽입하고, 이전 값이 더 이상 유효하지 않은 경우 부모 포인터를 업데이트합니다. childRows() 의 non-const 오버로드는 행 데이터에 대한 쓰기 액세스 기능도 추가로 제공합니다.

참고: 이 모델은 행의 부모를 설정하고, 기존 부모에서 해당 행을 제거하며, 새로운 부모의 자식 목록에 해당 행을 추가하는 작업을 별도의 단계로 수행합니다. 이를 통해 프로토콜 인터페이스를 간결하게 유지합니다.

    ...
    // Helper to assembly a tree of rows, not used by QRangeModel
    template <typename ...Args>
    TreeRow &addChild(Args &&...args)
    {
        if (!m_children)
            m_children.emplace(Tree{});
        auto &child = m_children->emplace_back(std::forward<Args>(args)...);
        child.m_parent = this;
        return child;
    }
};

클래스 구현의 나머지 부분은 이 모델과 관련이 없지만, ` addChild() ` 헬퍼 함수는 트리의 초기 상태를 편리하게 구성할 수 있는 방법을 제공합니다.

Tree tree = {
    {"..."},
    {"..."},
    {"..."},
};

// each toplevel row has three children
tree[0].addChild("...");
tree[0].addChild("...");
tree[0].addChild("...");

tree[1].addChild("...");
tree[1].addChild("...");
tree[1].addChild("...");

tree[2].addChild("...");
tree[2].addChild("...");
tree[2].addChild("...");

이러한 범위의 인스턴스로 인스턴스화된 QRangeModel은 데이터를 트리 형태로 표현합니다.

// instantiate the model with a pointer to the tree, not a copy!
QRangeModel model(&tree);
QTreeView view;
view.setModel(&model);

별도의 클래스에 구현된 트리 탐색 프로토콜

트리 탐색 프로토콜은 별도의 클래스에서 구현할 수도 있습니다.

struct TreeTraversal
{
    TreeRow newRow() const { return TreeRow{}; }
    const TreeRow *parentRow(const TreeRow &row) const { return row.m_parent; }
    void setParentRow(TreeRow &row, TreeRow *parent) const { row.m_parent = parent; }
    const std::optional<Tree> &childRows(const TreeRow &row) const { return row.m_children; }
    std::optional<Tree> &childRows(TreeRow &row) const { return row.m_children; }
};

이 프로토콜 구현체의 인스턴스를 QRangeModel 생성자에 전달합니다:

QRangeModel model(&tree, TreeTraversal{});

포인터 또는 값으로서의 트리 행

데이터 범위의 행 유형은 값이거나 포인터일 수 있습니다. 위 코드에서는 트리 행을 벡터 내의 값으로 사용해 왔는데, 이는 명시적인 메모리 관리를 처리할 필요가 없도록 해줍니다. 그러나 벡터는 연속된 메모리 블록이므로, 저장 공간을 재할당하거나 요소를 삽입·제거할 때 모든 이터레이터와 참조가 무효화됩니다. 이는 벡터 내 부모 행의 위치를 나타내는 부모 항목에 대한 포인터에도 영향을 미칩니다. 이 부모(및 그 내부의 항목을 참조하는 ` QPersistentModelIndex ` 인스턴스)가 유효한 상태를 유지하도록 보장하는 것은 상당한 성능 오버헤드를 초래할 수 있습니다. `QRangeModel` 구현은 범위를 수정할 때 해당 범위 내의 모든 참조가 무효화된다고 가정해야 합니다.

대안으로, 행 포인터의 범위를 트리 유형으로 사용할 수도 있습니다:

struct TreeRow;
using Tree = std::vector<TreeRow *>;

이 경우, ` new` 연산자를 사용하여 모든 `TreeRow` 인스턴스를 명시적으로 할당해야 하며, 자식 벡터에 포함된 모든 항목을 ` delete `로 처리하기 위해 소멸자를 구현해야 합니다.

struct TreeRow
{
    Q_GADGET
public:
    TreeRow(const QString&value = {})
        : m_value(value)
    {}
    ~TreeRow()
    {
        if (m_children)
            qDeleteAll(*m_children);
    }

    // 이동 전용
    TreeRow(TreeRow&&) = default;
    TreeRow&operator=(TreeRow&&) = default;

   // 데이터 채우기용 헬퍼 함수
    template <typename...Args>
    TreeRow *addChild(Args&&...args)
    {
        if (!m_children)
            m_children.emplace(Tree{});
       auto *child = m_children->emplace_back(new TreeRow(std::forward<Args>(args)...));
        child->m_parent = this;
        return child;
    }

private:
    friend struct TreeTraversal;
    QString m_value;
    std::optional<Tree> m_children;
    TreeRow *m_parent = nullptr;
};
Tree tree = {
    new TreeRow("1"),
    new TreeRow("2"),
    new TreeRow("3"),
    new TreeRow("4"),
};
tree[0]->addChild("1.1");
tree[1]->addChild("2.1");
tree[2]->addChild("3.1")->addChild("3.1.1");
tree[3]->addChild("4.1");

이 데이터를 트리 형태로 표현하는 모델을 구축하기 전에, 트리 탐색 프로토콜도 구현해야 합니다.

struct TreeTraversal
{
    TreeRow *newRow() const { return new TreeRow; }
    void deleteRow(TreeRow *row) { delete row; }

    const TreeRow *parentRow(const TreeRow &row) const { return row.m_parent; }
    void setParentRow(TreeRow &row, TreeRow *parent) { row.m_parent = parent; }
    const std::optional<Tree> &childRows(const TreeRow &row) const { return row.m_children; }
    std::optional<Tree> &childRows(TreeRow &row) { return row.m_children; }
};

포인터로 구성된 가변 트리에 대한 명시적 프로토콜 구현은 newRow() 와 deleteRow(RowType *) 라는 두 가지 추가 멤버 함수를 제공해야 합니다.

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    Tree tree = make_tree_of_pointers();

    QRangeModel model(std::move(tree), TreeTraversal{});
    QTreeView treeView;
    treeView.setModel(&model);
    treeView.show();

    return app.exec();
}

모델은 insertRows()에서 새 행을 생성할 때와 removeRows()에서 행을 제거할 때 해당 함수를 호출합니다. 또한, 모델이 데이터에 대한 소유권을 가지고 있는 경우, 소멸 시 모든 최상위 행을 삭제합니다. 이 예제에서 트리를 모델로 이동시켰으므로, 더 이상 트리에 대한 어떠한 작업도 수행할 필요가 없다는 점에 유의하십시오. 행 포인터가 포함된 트리 데이터를 모델로 이동시켜 QRangeModel을 생성하면, 모델이 데이터에 대한 소유권을 갖게 되며 소멸자에서 해당 행 포인터를 삭제합니다.

포인터를 행으로 사용하면 메모리 할당 및 관리에 약간의 오버헤드가 발생합니다. 그러나 행 항목에 대한 참조는 범위 내에서 이동되거나 범위가 재할당될 때에도 안정적으로 유지됩니다. 이를 통해 ` insertRows()`, ` removeRows()` 또는 ` moveRows()`를 사용할 때 모델 구조를 수정하는 데 드는 비용을 크게 줄일 수 있습니다.

각 선택지마다 성능과 메모리 오버헤드 간의 상충 관계가 다릅니다. 최선의 선택은 구체적인 사용 사례와 사용되는 데이터 구조에 따라 달라집니다.

템플릿 특화를 통한 사용자 정의

QRangeModel은 기본 동작을 재정의하기 위해 특수화할 수 있는 두 개의 중첩된 템플릿 유형을 선언합니다.

앞서 소개한 ` RowOptions ` 템플릿은 헤더 데이터와 같이 행 유형에 특화된 기능을 사용자 정의하거나, 기본 플래그와 같이 행 내 모든 항목에 일률적으로 적용되어야 하는 기능을 사용자 정의하는 데 사용됩니다. ` ItemAccess ` 템플릿을 사용하면 역할 데이터 읽기 또는 쓰기와 같이 항목 유형별 동작을 사용자 정의할 수 있습니다.

이 두 템플릿은 항상 기본이 되는 타입에 대해 특수화되어야 하므로, 범위에 Row 타입의 행이 std::unique_ptr<Row> 로 포함되어 있거나, Item 타입의 항목이 std::shared_ptr<Item> 로 포함되어 있더라도, 특수화는 Row 및 Item 에 대해 이루어져야 합니다.

template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
    ...
};
std::vector<std::shared_ptr<ColorEntry>> colors;
// ...
QRangeModel model(colors);

참고: C++에서는 표준 타입이나 Qt 타입이 아닌, 자신이 소유한 타입에 대해서만 템플릿을 특화해야 합니다. 제어할 수 없는 타입의 동작을 사용자 정의해야 하는 경우, 해당 타입에 대한 서브클래스나 집합체를 생성하십시오. 유형 별칭(type alias)은 별개의 유형이 아니므로, 별칭 유형에 대해서는 템플릿을 특화해서는 안 됩니다. 그러나 ` std::vector<MyGadget>`과 같이 자신이 소유한 유형을 사용하여 표준 또는 Qt 컨테이너의 특화 버전을 만드는 것은 허용됩니다.

행 및 항목별 플래그

flags()의 기본 구현은 Qt::ItemIsSelectable, Qt::ItemIsEnabled, 그리고 트리 모델의 0번 열에 있는 항목을 제외하고는 Qt::ItemNeverHasChildren 의 조합을 반환합니다. Qt::ItemIsEditable 및 Qt::ItemIsDropEnabled 플래그는 읽기 전용이 아닌 모델의 모든 항목에 대해 설정되며, 모델이 적어도 하나의 mime type 을 지원하는 한 Qt::ItemIsDragEnabled 가 설정됩니다.

행 내의 모든 항목에 대한 기본 동작을 사용자 정의하려면 RowOptions 템플릿을 특화하십시오. 항목별 플래그 데이터에 액세스하려면 ItemAccess 템플릿을 특화하십시오. 두 가지 방법을 모두 사용할 수 있습니다. RowOptions 을 통해 행 내의 모든 항목에 공통적으로 적용되는 플래그를 설정할 수 있으며, ItemAccess 을 통해 특정 유형을 기반으로 하는 항목에 대한 플래그를 설정할 수 있습니다.

드래그 앤 드롭 처리

Qt 6.12부터 QRangeModel은 모델이 적어도 하나의 mime type 을 지원하는 경우, 모델 내의 모든 유효한 항목에 대해 Qt::ItemIsDragEnabled 플래그를 설정하는 flags() 가상 함수를 구현합니다. QAbstractItemModel 이 Qt 내부 MIME 유형인 "application/x-qabstractitemmodeldatalist"를 제공하므로, 이것이 기본값입니다. 또한, 해당 모델이 읽기 전용이 아닌 한, 해당 모델의 항목에 대해 Qt::ItemIsDropEnabled 플래그가 설정됩니다. 여기에는 유효하지 않은 인덱스에 위치한 존재하지 않는 항목도 포함되므로, 사용자는 뷰의 빈 영역에 데이터를 드롭하여 데이터를 추가할 수 있습니다.

QRangeModel을 서브클래싱하거나 해당 가상 함수를 오버라이드하지 않고도 추가 MIME 유형에 대한 지원을 구현할 수 있습니다. QRangeModel은 ItemAccess 및 RowOptions 사용자 정의 템플릿 내의 함수를 감지하여 이를 활용함으로써, 행이나 항목을 mime data 로 인코딩하고, decode mime data 를 통해 행이나 항목의 시퀀스로 변환합니다. 이러한 사용자 정의 함수는 QModelIndex 및 QVariant 를 경유하지 않고도 행 및 항목 유형에 직접 작동할 수 있습니다.

이렇게 하면 데이터 직렬화 코드가 유형 안전성을 확보할 수 있으며, 데이터를 저장하는 데 사용되는 유형의 구현과 함께 유지될 수 있습니다.

또한, supportedDragActions 및 supportedDropActions 는 각 QRangeModel 인스턴스에 대해 구성할 수 있는 속성입니다.

고급 C++ 주제

C++ 튜플 프로토콜

위의 ` numberNames ` 예제에서 볼 수 있듯이, 행(row) 유형은 튜플일 수 있으며, 사실 튜플 프로토콜을 구현하는 모든 유형이 될 수 있습니다. 이 프로토콜은 ` std::tuple_size ` 및 ` std::tuple_element`을 특화(specialize)하고, 한정되지 않은 ` get ` 함수를 오버로딩함으로써 구현됩니다. 사용자 정의 행 유형에 대해 이를 적용하면 Qt의 모델/뷰 프레임워크에서 기존 구조화된 데이터를 활용할 수 있습니다.

struct Book
{
    QString title;
    QString author;
    QString summary;
    int rating = 0;

    template <size_t I, typename T>
        requires ((I <= 3) && std::is_same_v<std::remove_cvref_t<T>, Book>)
    friend inline decltype(auto) get(T &&book)
    {
        if constexpr (I == 0)
            return std::as_const(book.title);
        else if constexpr (I == 1)
            return std::as_const(book.author);
        else if constexpr (I == 2)
            return std::forward_like<T>(book.summary);
        else if constexpr (I == 3)
            return std::forward_like<T>(book.rating);
    }
};

namespace std {
    template <> struct tuple_size<Book> : std::integral_constant<size_t, 4> {};
    template <size_t I> struct tuple_element<I, Book>
    { using type = decltype(get<I>(std::declval<Book>())); };
}

위의 구현에서, ` Book ` 타입의 ` title ` 및 ` author ` 값은 ` const`로 반환되므로, 모델은 해당 두 열의 항목을 읽기 전용으로 표시합니다. 사용자는 편집을 시작할 수 없으며, ` setData()`는 아무 작업도 수행하지 않고 `false`를 반환합니다. summary 및 rating 의 경우, 구현은 책과 동일한 값 범주를 반환하므로, Book 에 대한 가변 참조를 사용하여 get 를 호출하면 해당 변수의 가변 참조가 반환됩니다. 모델은 사용자 및 프로그래밍 방식의 액세스 모두에 대해 해당 열을 편집 가능하게 만듭니다.

참고: 위의 get 구현은 C++23이 필요합니다.

바이너리 호환성 고려 사항

QRangeModel은 템플릿 클래스가 아닙니다. (모든 QObject 클래스와 마찬가지로 포인터나 참조를 통해) 라이브러리 API를 통해 QRangeModel 인스턴스를 전달하거나, 라이브러리의 공개 클래스에 QRangeModel을 값으로 저장하는 것은 안전합니다.

그러나 QRangeModel 생성자는 템플릿이자 인라인이며, 모델이 처리하는 범위의 유형에 따라 특화된 내부 구현이 생성자 내에서 인스턴스화됩니다. 라이브러리 API의 인라인 구현 내에서 이 생성자를 호출해서는 안 됩니다. 이는 ODR 위반을 초래하며, 해당 라이브러리를 빌드하는 데 사용된 Qt 버전이 해당 라이브러리를 사용하는 애플리케이션이 빌드된 Qt 버전과 다를 경우, 해당 라이브러리의 바이너리 호환성을 깨뜨릴 수 있습니다.

QRangeModel이 구현이 이전 버전의 Qt를 기준으로 컴파일된 것으로 감지하는 경우, Qt의 후속 버전에서 도입된 가상 함수의 새로운 구현이나 최적화된 구현이 사용되지 않을 수도 있습니다. 예를 들어, ` sort()` 및 ` match()`의 구현은 Qt 6.12에서 새로 추가되었지만, 사용된 Qt 라이브러리가 Qt 6.12라 하더라도 Qt 6.11을 대상으로 컴파일된 애플리케이션에서는 호출되지 않습니다. 이러한 새로운 오버라이드의 이점을 얻으려면 애플리케이션을 다시 컴파일하십시오.

QRangeModelAdapter, QAbstractItemModel, QStandardItemModel 및 Model/View 프로그래밍항목도 참조하십시오 .

멤버 유형 문서

[since 6.11] enum class QRangeModel::AutoConnectPolicy

이 열거형은 ‘ QRangeModel ’가 속성의 ‘changed-signals’를 모델의 ‘ dataChanged()’ 신호에 자동으로 연결할지 여부와 그 시점을 정의합니다. ‘ role names ’ 중 하나에 해당하는 속성만 연결됩니다.

상수값설명
QRangeModel::AutoConnectPolicy::None0자동으로 연결이 이루어지지 않습니다.
QRangeModel::AutoConnectPolicy::Full1모든 관련 속성에 대한 신호가 모든 QObject 항목에 대해 자동으로 연결됩니다. 여기에는 새로 삽입된 행과 열에 추가된 QObject 항목도 포함됩니다.
QRangeModel::AutoConnectPolicy::OnRead2관련 속성에 대한 신호는 모델이 해당 속성을 처음 읽을 때 연결됩니다.

자동 연결을 설정할 때 발생하는 메모리 오버헤드는 상당할 수 있습니다. '완전 자동 연결(Full auto-connection)'은 연결 자체 외에 별도의 관리 작업이 필요하지 않지만, 각 연결마다 메모리를 차지하며, 특히 객체 하위 집합의 몇 가지 속성만 변경되는 경우 모든 객체의 모든 속성을 연결하는 데는 상당한 비용이 소요될 수 있습니다.

OnRead 연결 정책은 읽히지 않는(예를 들어, 뷰에 렌더링되지 않는) 객체나 속성에는 연결하지 않지만, 어떤 연결이 이루어졌는지 기억하는 데는 약간의 관리 오버헤드가 필요하며, 시간이 지남에 따라 예측할 수 없는 메모리 증가가 발생할 수 있습니다. 예를 들어, 긴 항목 목록을 아래로 스크롤하면 수천 개의 새로운 연결이 쉽게 생성될 수 있습니다.

이 열거형은 Qt 6.11에서 도입되었습니다.

autoConnectPolicy 및 roleNames()도 참조하십시오 .

[since 6.12] enum class QRangeModel::DropOperation

이 열거형은 ` dropMimeData()` 사용자 정의에서 디코딩된 데이터가 모델에 어떻게 기록되는지를 정의합니다.

상수값설명
QRangeModel::DropOperation::DontDrop0데이터를 모델에 추가해서는 안 됩니다.
QRangeModel::DropOperation::Automatic1Qt는 데이터가 모델에 추가되는 방식을 결정합니다.
QRangeModel::DropOperation::OverwriteAndIgnore2드롭된 항목과 그 뒤의 항목들을 덮어쓰고, 들어가지 않는 드롭된 데이터는 모두 버립니다.
QRangeModel::DropOperation::OverwriteAndExtend3드롭된 항목과 그 뒤의 항목들을 덮어쓰고, 드롭된 모든 데이터가 들어갈 수 있도록 모델의 크기를 늘립니다.
QRangeModel::DropOperation::InsertAsSiblings4드롭된 모든 데이터를 드롭 대상 항목의 형제 노드로 삽입합니다.
QRangeModel::DropOperation::InsertAsChildren5드롭된 모든 데이터를 드롭 대상 항목의 자식으로 삽입합니다.

dropMimeData() 사용자 정의는 대신 bool 값을 반환할 수 있으며, 이 경우 false 는 DontDrop 값에, true 는 Automatic에 매핑됩니다.

이 열거형은 Qt 6.12에서 도입되었습니다.

canDropMimeData() 및 dropMimeData()도 참조하십시오 .

enum class QRangeModel::RowCategory

이 열거형은 ` QRangeModel `가 생성 시 지정된 범위의 요소를 어떻게 표시해야 하는지를 정의합니다.

상수값상수값
QRangeModel::RowCategory::Default0QRangeModel 행의 표시 방식을 결정합니다.
QRangeModel::RowCategory::MultiRoleItem1QRangeModel 는 1차원 범위에서 사용될 때도 메타 객체가 있는 항목을 다중 역할 항목으로 표시합니다.

사용하는 타입에 맞게 ` RowOptions ` 템플릿을 특수화하고, 이 열거형의 값 중 하나를 가진 공용 멤버 변수 ` static constexpr auto rowCategory `를 추가하십시오.

RowOptions도 참조하십시오 .

속성 문서

[since 6.11] autoConnectPolicy : AutoConnectPolicy

모델이 속성 변경 알림에 자동으로 연결될 경우.

QRangeModel 가 행(row) 또는 항목(item) 유형과 동일한 유형의 QObject 하위 클래스를 포함하는 데이터 구조를 처리하는 경우, QObject의 속성을 dataChanged() 신호에 자동으로 연결할 수 있습니다. QObject 행의 경우, 각 열에 대해 Qt::DisplayRole 속성에 매핑하여 이 작업이 수행됩니다. 항목의 경우, role names 중 하나와 일치하는 속성에 대해 이 작업이 수행됩니다.

기본적으로 이 속성의 값은 None 이므로, 이러한 연결은 생성되지 않습니다. 이 속성의 값을 변경하면 항상 기존의 모든 연결이 끊어집니다.

참고: QRangeModel 가 처리하는 데이터 구조 내의 QObject가 스왑아웃되더라도연결은 끊어지거나 생성되지 않습니다.

이 열거형은 Qt 6.11에서 도입되었습니다.

액세스 함수:

QRangeModel::AutoConnectPolicy autoConnectPolicy() const
void setAutoConnectPolicy(QRangeModel::AutoConnectPolicy policy)

Notifier 신호:

void autoConnectPolicyChanged(QRangeModel::AutoConnectPolicy policy)

roleNames()도 참조하십시오 .

roleNames : QHash<int, QByteArray>

이 속성은 모델의 역할 이름을 포함합니다.

범위 내의 모든 열이 동일한 유형이고, 해당 유형이 메타 객체를 제공하는 경우(즉, 가젯이거나 ` QObject `의 하위 클래스인 경우), 이 속성은 해당 유형의 속성 이름을 포함하며, 이 속성들은 Qt::UserRole 부터 시작하는 ` Qt::ItemDataRole ` 값에 매핑됩니다. 또한, “modelData” 역할은 가젯 또는 QObject 인스턴스에 대한 액세스를 제공합니다.

이 속성을 비어 있지 않은 매핑으로 명시적으로 설정하여 이 기본 동작을 재정의할 수 있습니다. 이 속성을 빈 매핑으로 설정하거나 resetRoleNames()를 사용하면 기본 동작으로 복원됩니다.

액세스 함수:

virtual QHash<int, QByteArray> roleNames() const override
void setRoleNames(const QHash<int, QByteArray> &names)
void resetRoleNames()

Notifier 시그널:

void roleNamesChanged()

QAbstractItemModel::roleNames()도 참조하십시오 .

[since 6.12] sortCollator : QCollator

이 속성은 모델을 정렬할 때 사용될 콜레이터를 저장합니다.

이 속성의 기본값은 C 로케일에 대한 ` QCollator `입니다. 정렬은 로케일을 고려하지 않으며 대소문자를 구분합니다. 콜레이터를 설정하면 정렬이 로케일을 고려하게 됩니다.

이 열거형은 Qt 6.12에서 도입되었습니다.

액세스 함수:

QCollator sortCollator() const
void setSortCollator(const QCollator &collator)
void resetSortCollator()

알림 신호:

void sortCollatorChanged(const QCollator &collator)

sort(), sortRole 및 QSortFilterProxyModel도 참조하십시오 .

[since 6.12] sortRole : int

이 속성은 항목을 정렬할 때 사용되는 데이터 역할을 저장합니다.

기본값은 ` Qt::DisplayRole`입니다.

이 열거형은 Qt 6.12에서 도입되었습니다.

액세스 함수:

int sortRole() const
void setSortRole(int role)
void resetSortRole()

알림 신호:

void sortRoleChanged(int role)

sort(), sortCollator 및 QSortFilterProxyModel도 참조하십시오 .

[since 6.12] supportedDragActions : Qt::DropActions

이 속성은 이 모델에서 지원하는 드래그 동작을 포함합니다.

읽기 전용 모델에서 데이터를 이동하는 것과 같이 모델이 지원할 수 없는 동작은 동작을 설정할 때 제거됩니다.

참고: ` QRangeModel ` 하위 클래스에서 이 함수를재정의하는 것은 가능하지만, 속성의 동작에 문제를 일으킬 수 있습니다.

이 열거형은 Qt 6.12에서 도입되었습니다.

액세스 함수:

virtual Qt::DropActions supportedDragActions() const override
void setSupportedDragActions(Qt::DropActions actions)
void resetSupportedDragActions()

Notifier 신호:

void supportedDragActionsChanged(Qt::DropActions actions)

supportedDropActions도 참조하십시오 .

[since 6.12] supportedDropActions : Qt::DropActions

이 속성은 이 모델에서 지원하는 드롭 동작을 포함합니다.

읽기 전용 모델은 어떤 드롭 동작도 지원할 수 없습니다.

참고: ` QRangeModel ` 하위 클래스에서 이 함수를재정의하는 것은 가능하지만, 속성의 동작에 문제를 일으킬 수 있습니다.

이 열거형은 Qt 6.12에서 도입되었습니다.

액세스 함수:

virtual Qt::DropActions supportedDropActions() const override
void setSupportedDropActions(Qt::DropActions actions)
void resetSupportedDropActions()

Notifier 신호:

void supportedDropActionsChanged(Qt::DropActions actions)

supportedDragActions도 참조하십시오 .

멤버 함수 문서

[explicit] template <typename Range, int = true> QRangeModel::QRangeModel(Range &&range, QObject *parent = nullptr)

[explicit] template <typename Range, int = true> QRangeModel::QRangeModel(Range &&range, QObject *parent = nullptr)

[explicit] template < typename Range, typename Protocol, int = true > QRangeModel::QRangeModel(Range &&range, Protocol &&protocol, QObject *parent = nullptr)

range 에 있는 데이터를 처리하는 QRangeModel 인스턴스를 생성합니다. range 는 컴파일러가 인자 의존적 조회( argument dependent lookup) 를 통해 begin 및 end 오버로드를 찾을 수 있거나, std::begin 및 std::end 가 구현된 순차적 범위여야 합니다. protocol 가 제공되면, 모델은 프로토콜 구현을 사용하여 해당 범위를 트리로 표현합니다. 모델 인스턴스는 parent 의 자식이 됩니다.

range 는 포인터나 참조 래퍼일 수 있으며, 이 경우 모델의 변형 API(예: setData() 또는 insertRow()))를 호출하면 참조된 범위 인스턴스의 데이터가 수정됩니다. range 가 값(또는 모델로 이동된)인 경우, 데이터 변경에 대응하기 위해 모델이 발산하는 신호에 연결해야 합니다.

QRangeModel 이 생성자는 생성되는 동안 range 에 접근하지 않습니다. 따라서 subclassing QRangeModel 와 같이, 아직 완전히 생성되지 않은 범위 객체에 대한 포인터나 참조를 이 생성자에 전달하는 것이 허용됩니다.

range 가 모델로 이동된 경우, 모델이 소멸되면 범위와 그 안의 모든 데이터가 소멸됩니다.

참고: 모델이 다른 방식으로는 범위 객체의 소유권을 인수하지는않지만 , 모델이 생성되어 뷰로 전달된 후에는 range 를 직접 수정해서는 안 됩니다. 이러한 수정은 모델 사용자(다른 모델이나 뷰)가 모델과 동기화를 유지하는 데 필요한 신호를 발생시키지 않으므로, 결과적으로 일관성 없는 결과, 정의되지 않은 동작 및 충돌을 초래할 수 있습니다. 모델을 최신 상태로 유지하면서 기본 레인지와 안전하게 상호작용하려면 ` QRangeModelAdapter `를 사용하십시오.

QRangeModelAdapter도 참조하십시오 .

[override virtual noexcept] QRangeModel::~QRangeModel()

QRangeModel 를 파괴합니다.

모델이 생성된 범위에는 접근할 수 없으며, 모델이 이동된 범위에서 생성된 경우에만 파기됩니다.

[override virtual] QModelIndex QRangeModel::buddy(const QModelIndex &index) const

QAbstractItemModel::buddy(const QModelIndex &index) const를 재구현합니다.

[override virtual] bool QRangeModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const

QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const를 재구현합니다.

범위에 저장된 항목 유형에 대해 ItemAccess 의 사용자 정의가 사용 가능하고, 해당 사용자 정의가 적절한 canDropMimeData() 클래스 멤버 함수를 구현하는 경우, 이 구현은 해당 함수를 호출하여 결과를 반환합니다.

template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
    static bool canDropMimeData(const QMimeData *mimeData)
    {
        // ...
        return true;
    }
};

그렇지 않은 경우, 범위 내의 행 유형에 대해 적절한 canDropMimeData() 클래스 멤버 함수를 가진 RowOptions 의 사용자 정의가 있다면, 이 구현은 해당 함수를 호출한 결과를 반환합니다.

template <>
struct QRangeModel::RowOptions<ColorEntry>
{
    static bool canDropMimeData(const QMimeData *mimeData)
    {
        // ...
        return true;
    }
};

두 사용자 정의 구현 모두 사용할 수 없는 경우, 이 구현은 기본 QAbstractItemModel 구현의 결과를 반환합니다.

Drag'n'drop handling, RowOptions::canDropMimeData(), ItemAccess::canDropMimeData(), dropMimeData(), mimeTypes() 및 mimeData()도 참조하십시오 .

[override virtual] bool QRangeModel::canFetchMore(const QModelIndex &parent) const

QAbstractItemModel::canFetchMore(const QModelIndex &parent) const를 재구현합니다.

[override virtual] bool QRangeModel::clearItemData(const QModelIndex &index)

QAbstractItemModel::clearItemData(const QModelIndex &index)를 재구현합니다.

index 에 지정된 범위 내에 저장된 값을 기본 생성된 값으로 대체합니다.

읽기 전용 범위에서 작동하는 모델이나, ` the C++ tuple protocol`를 구현하는 행 유형의 읽기 전용 열에서 작동하는 모델의 경우, 이 구현은 즉시 ` false `를 반환합니다.

[override virtual] int QRangeModel::columnCount(const QModelIndex &parent = {}) const

다음 함수를 재구현합니다: ` QAbstractItemModel::columnCount(const QModelIndex &parent) const`.

모델의 열 수를 반환합니다. 이 함수는 모든 parent 인덱스에 대해 동일한 값을 반환합니다.

정적 크기의 행 유형을 사용하는 모델의 경우, 이 반환 값은 모델의 수명 기간 내내 항상 동일합니다. 동적 크기의 행 유형을 사용하는 모델의 경우, 모델은 첫 번째 행의 항목 수를 반환하며, 행이 없는 경우에는 0을 반환합니다.

rowCount 및 insertColumns()도 참조하십시오 .

[override virtual] QVariant QRangeModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const

QAbstractItemModel::data(const QModelIndex &index, int role) const를 재구현합니다.

index 가 가리키는 범위 내의 값에 대해, 주어진 role 에 저장된 데이터를 반환합니다.

해당 인덱스의 항목 유형이 int, Qt::ItemDataRole 또는 QString 에서 QVariant 로 매핑되는 연관 컨테이너인 경우, 해당 컨테이너에서 역할 데이터를 조회하여 반환합니다.

항목이 가젯이거나 QObject 인 경우, 구현체는 roleNames() 매핑에서 role 항목과 일치하는 항목 속성의 값을 반환합니다.

그렇지 않은 경우, 구현체는 Qt::DisplayRole 또는 Qt::EditRole 에 대한 QVariant::fromValue() 을 통해 항목으로 구성된 QVariant 를 반환합니다. 다른 역할의 경우, 구현체는 유효하지 않은 (기본 생성된) QVariant 를 반환합니다.

Qt::ItemDataRole, setData(), headerData()도 참조하십시오 .

[override virtual] bool QRangeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)

QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)를 재구현합니다.

범위에 저장된 항목 유형에 대해 ` ItemAccess `의 사용자 정의가 존재하고, 해당 사용자 정의가 적절한 ` dropMimeData()` 클래스 멤버 함수를 구현하고 있다면, 이 구현은 해당 함수를 호출하여 그 결과를 반환합니다.

template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
    static bool dropMimeData(const QMimeData *mimeData, auto inserter)
    {
        QByteArray data = mimeData->data(mimeTypes().first());
        if (data.isEmpty())
            return false;
        QTextStream stream(&data, QIODevice::ReadOnly);
        while (!stream.atEnd()) {
            QString colorName;
            stream >> colorName;
            inserter = ColorEntry(colorName);
        }
        return true;
    }
};

그렇지 않은 경우, 범위 내의 행 유형에 대해 적절한 dropMimeData() 클래스 멤버 함수를 가진 RowOptions 의 사용자 정의가 있다면, 이 구현은 해당 함수를 호출한 결과를 반환합니다.

template <>
struct QRangeModel::RowOptions<ColorEntry>
{
    static bool dropMimeData(const QMimeData *mimeData, auto inserter)
    {
        const QByteArray data = mimeData->data(mimeTypes().first());
        if (data.isEmpty())
            return false;
        QXmlStreamReader stream(data);
        while (!stream.atEnd()) {
            stream.readNext();
            if (stream.isStartElement() && stream.name() == u"li"_s)
                inserter = ColorEntry(stream.readElementText());
        }

        return true;
    }
};

두 사용자 정의 구현 모두 사용할 수 없는 경우, 이 구현은 QAbstractItemModel 의 기본 구현 결과를 반환합니다.

Drag'n'drop handling, RowOptions::dropMimeData(), ItemAccess::dropMimeData(), canDropMimeData(), mimeTypes() 및 mimeData()도 참조하십시오 .

[override virtual protected] bool QRangeModel::event(QEvent *event)

QObject::event(QEvent *e)를 재구현합니다.

[override virtual protected] bool QRangeModel::eventFilter(QObject *object, QEvent *event)

QObject::eventFilter(QObject *watched, QEvent *event)를 재구현합니다.

[override virtual] void QRangeModel::fetchMore(const QModelIndex &parent)

QAbstractItemModel::fetchMore(const QModelIndex &parent)를 재구현합니다.

[override virtual] Qt::ItemFlags QRangeModel::flags(const QModelIndex &index) const

QAbstractItemModel::flags(const QModelIndex &index) const를 재구현합니다.

주어진 index 에 대한 항목 플래그를 반환합니다.

이 구현은 항목(ItemIsEnabled)을 활성화하고 선택할 수 있게 하는(ItemIsSelectable) 플래그 조합을 반환합니다. 변경 가능한 데이터가 포함된 범위를 다루는 모델의 경우, 항목을 편집할 수 있게 하는(ItemIsEditable) 플래그도 설정합니다.

mimeTypes()의 비어 있지 않은 리스트를 반환하는 모델은 Qt::ItemIsDragEnabled 도 설정하며, 읽기 전용이 아닌 한 Qt::ItemIsDropEnabled 플래그도 설정합니다.

플랫 모델은 모든 항목에 대해 Qt::ItemNeverHasChildren 를 설정하는 반면, 계층형 모델은 0보다 위쪽 열에 있는 모든 항목에 대해 해당 플래그를 설정합니다.

자신만의 데이터 유형에 맞게 플래그를 사용자 정의하려면, 행 또는 항목 유형에 대한 RowOptions 및/또는 ItemAccess 의 특화 버전을 제공하고 flags() 정적 멤버 함수를 구현하십시오:

template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
    static Qt::ItemFlags flags(const ColorEntry &entry)
    {
        return entry.flags();
    }
};

Qt::ItemFlags, RowOptions 및 ItemAccess도 참조하십시오 .

[override virtual] bool QRangeModel::hasChildren(const QModelIndex &parent = QModelIndex()) const

QAbstractItemModel::hasChildren(const QModelIndex &parent) const를 재구현합니다.

[override virtual] QVariant QRangeModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const

QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const를 재구현합니다.

지정된 orientation 을 가진 헤더에서, 주어진 role 및 section 에 해당하는 데이터를 반환합니다.

가로 방향 헤더의 경우, 섹션 번호는 열 번호에 해당합니다. 마찬가지로, 세로 방향 헤더의 경우, 섹션 번호는 행 번호에 해당합니다.

수평 헤더 및 Qt::DisplayRole role 의 경우, 행 유형으로 배열을 사용하는 범위를 처리하는 모델은 section 를 반환합니다. 행 유형이 튜플인 경우, 구현은 section 에 있는 유형의 이름을 반환합니다. 가젯(gadget) 또는 QObject 유형인 행의 경우, 이 함수는 section 인덱스에 있는 속성의 이름을 반환합니다.

사용자 정의 범위에 대한 가로 헤더 데이터를 사용자 정의하려면, 행 유형에 대해 RowOptions 의 특수화를 제공하고 headerData() 클래스 멤버 함수를 구현하십시오:

template <>
struct QRangeModel::RowOptions<ColorEntry>
{
    static QVariant headerData(int section, int role)
    {
        switch (section) {
            // ...
        }
        return {};
    }
};

수직 헤더의 경우, 이 함수는 항상 QAbstractItemModel 의 기본 구현 결과를 반환합니다.

Qt::ItemDataRole, setHeaderData(), QHeaderView 및 RowOptions도 참조하십시오 .

[override virtual] QModelIndex QRangeModel::index(int row, int column, const QModelIndex &parent = {}) const

QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const를 재구현합니다.

parent 에서 row 및 column 위치에 있는 모델 항목의 인덱스를 반환합니다.

유효한 부모를 전달하면 목록 및 테이블 범위를 처리하는 모델의 경우 유효하지 않은 인덱스가 생성됩니다.

parent()도 참조하십시오 .

[override virtual] bool QRangeModel::insertColumns(int column, int count, const QModelIndex &parent = {})

QAbstractItemModel::insertColumns(int column, int count, const QModelIndex &parent)를 재구현합니다.

parent 에 지정된 범위의 모든 행에서 column 에 있는 항목 앞에 count 개의 빈 열을 삽입합니다. 성공하면 true 을 반환하고, 그렇지 않으면 false 을 반환합니다.

참고: 동적 크기의 행유형은 insert(const_iterator, size_t, value_type) 멤버 함수를 제공해야 합니다.

읽기 전용 범위나 정적 크기의 행 유형(튜플, 배열, 구조체 등)을 가진 범위에서 작동하는 모델의 경우, 이 구현은 아무런 작업도 수행하지 않고 즉시 false 를 반환합니다. 트리 모델의 경우 항상 이 규칙이 적용됩니다.

[override virtual] bool QRangeModel::insertRows(int row, int count, const QModelIndex &parent = {})

QAbstractItemModel::insertRows(int row, int count, const QModelIndex &parent)을 재구현합니다.

지정된 ` row ` 앞쪽에 ` count ` 개의 빈 행을 ` parent` 위치의 범위 내에 삽입합니다. 성공하면 ` true `를 반환하고, 그렇지 않으면 ` false`를 반환합니다.

참고: 범위는 동적으로 크기가 조정되어야 하며 insert(const_iterator, size_t, value_type) 멤버 함수를 제공해야 합니다.

읽기 전용 또는 정적 크기의 범위(예: 배열)에서 작동하는 모델의 경우, 이 구현은 아무 작업도 수행하지 않고 즉시 ` false `를 반환합니다.

참고: 열 유형의 크기가 동적으로 결정되는 범위의경우 , 해당 열은 resize(size_t) 멤버 함수를 제공해야 합니다.

[override virtual] QMap<int, QVariant> QRangeModel::itemData(const QModelIndex &index) const

QAbstractItemModel::itemData(const QModelIndex &index) const를 재구현합니다.

index 에 지정된 모델 내의 항목에 대해, 모델에 미리 정의된 모든 역할의 값을 포함하는 맵을 반환합니다.

해당 index 의 항목 유형이 int, Qt::ItemDataRole 또는 QString 을 QVariant 로 매핑하는 연관 컨테이너인 경우, 해당 컨테이너의 데이터가 반환됩니다.

항목 유형이 가젯이나 QObject 의 하위 클래스인 경우, role name 에 해당하는 속성의 값이 반환됩니다.

항목이 연관 컨테이너, 가젯 또는 QObject 의 하위 클래스가 아닌 경우, 이 메서드는 기본 클래스의 구현을 호출합니다.

setItemData(), Qt::ItemDataRole 및 data()도 참조하십시오 .

[override virtual] QModelIndexList QRangeModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const

QAbstractItemModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const를 재구현합니다.

flags 에서 정의된 일치 기준을 사용하여, role 에 저장된 데이터가 value 와 일치하는 start 열 내 항목들의 인덱스 목록을 반환합니다. 모든 일치하는 항목을 찾으려면 hits = -1을 사용하십시오.

참고: 이 구현은 기본 C++ 범위에서 데이터를 직접 읽으며, data()의 오버라이드를 통해 디스패치하지 않습니다.

[override virtual] QMimeData *QRangeModel::mimeData(const QModelIndexList &indexes) const

QAbstractItemModel::mimeData(const QModelIndexList &indexes) const를 재구현합니다.

범위에 저장된 항목 유형에 대해 ` ItemAccess `의 사용자 정의가 존재하고, 해당 사용자 정의가 적절한 ` mimeData()` 클래스 멤버 함수를 구현하고 있는 경우, 이 구현은 해당 함수를 호출하여 결과를 반환합니다.

template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
    static QMimeData *mimeData(const auto &range)
    {
        QByteArray data;
        QTextStream stream(&data, QIODevice::WriteOnly);
        for (const auto &[item, index] : range)
            stream << item.colorName() << Qt::endl;

        QMimeData *result = new QMimeData;
        result->setData(mimeTypes().first(), data);
        // Qt handles encoding into the default mime type
        return result;
    }
};

그렇지 않은 경우, 범위 내의 행 유형에 대해 적절한 mimeData() 클래스 멤버 함수를 가진 RowOptions 의 사용자 정의가 있다면, 이 구현은 해당 함수를 호출한 결과를 반환합니다.

template <>
struct QRangeModel::RowOptions<ColorEntry>
{
    template <typename Items>
    static QMimeData *mimeData(const Items &items)
    {
        if (items.isEmpty())
            return nullptr;
        QByteArray data;
        QXmlStreamWriter stream(&data);
        stream.writeStartElement("ul");
        for (const auto &[item, index] : items)
            stream.writeTextElement("li", item.colorName());
        stream.writeEndElement();

        QMimeData *mimeData = new QMimeData;
        mimeData->setData(mimeTypes().first(), data);
        return mimeData;
    }
};

두 사용자 정의 구현 모두 사용할 수 없는 경우, 이 구현은 기본 QAbstractItemModel 구현의 결과를 반환합니다.

Drag'n'drop handling, RowOptions::mimeData(), ItemAccess::mimeData(), canDropMimeData(), dropMimeData() 및 mimeTypes()도 참조하십시오 .

[override virtual] QStringList QRangeModel::mimeTypes() const

QAbstractItemModel::mimeTypes() const를 재구현합니다.

범위에 저장된 항목 유형에 대해 ` ItemAccess `의 사용자 정의가 존재하고, 해당 사용자 정의가 적절한 ` mimeTypes()` 클래스 멤버 함수를 구현하고 있는 경우, 이 구현은 해당 함수를 호출하여 결과를 반환합니다.

template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
    static QStringList mimeTypes()
    {
        return {
            u"text/plain"_s,
            u"application/x-qabstractitemmodeldatalist"_s
        };
    }
};

그렇지 않은 경우, 범위 내의 행 유형에 대해 적절한 ` mimeTypes()` 클래스 멤버 함수를 가진 ` RowOptions `의 사용자 정의가 사용 가능한 경우, 이 구현은 해당 함수를 호출한 결과를 반환합니다.

template <>
struct QRangeModel::RowOptions<ColorEntry>
{
    static QStringList mimeTypes()
    {
        return {
            u"text/html"_s
        };
    }
};

두 사용자 정의 구현 모두 사용할 수 없는 경우, 이 구현은 기본 QAbstractItemModel 구현의 결과를 반환합니다.

Drag'n'drop handling, RowOptions::mimeTypes(), ItemAccess::mimeTypes(), canDropMimeData(), dropMimeData() 및 mimeData()도 참조하십시오 .

[override virtual] bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationColumn)

QAbstractItemModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild)를 재구현합니다.

지정된 sourceColumn 을 시작으로, 부모 노드 sourceParent 아래에 있는 count 열들을 부모 노드 destinationParent 아래의 destinationColumn 열로 이동합니다.

컬럼이 성공적으로 이동된 경우 true 를 반환하고, 그렇지 않은 경우 false 를 반환합니다.

[override virtual] bool QRangeModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationRow)

QAbstractItemModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)를 재구현합니다.

지정된 sourceRow 을 시작으로, 부모 노드 sourceParent 아래에 있는 count 행들을 부모 노드 destinationParent 아래의 행 destinationRow 으로 이동합니다.

행이 성공적으로 이동된 경우 true 를 반환하고, 그렇지 않은 경우 false 를 반환합니다.

[override virtual] void QRangeModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const

QAbstractItemModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const를 재구현합니다.

[override virtual] QModelIndex QRangeModel::parent(const QModelIndex &child) const

QAbstractItemModel::parent(const QModelIndex &index) const를 재구현합니다.

child 인덱스에 있는 항목의 부모를 반환합니다.

이 함수는 목록 및 테이블 범위를 다루는 모델의 경우 항상 유효하지 않은 인덱스를 반환합니다. 트리를 다루는 모델의 경우, 이 함수는 트리 탐색 프로토콜의 parent() 구현에서 반환된 행 항목의 인덱스를 반환합니다.

index() 및 hasChildren()도 참조하십시오 .

[override virtual] bool QRangeModel::removeColumns(int column, int count, const QModelIndex &parent = {})

QAbstractItemModel::removeColumns(int column, int count, const QModelIndex &parent)를 재구현합니다.

parent 에 지정된 범위의 모든 행에서 column 위치에 있는 항목에서 count 열을 제거합니다. 성공하면 true 를 반환하고, 그렇지 않으면 false 를 반환합니다.

참고: 동적 크기의 행유형은 ` erase(const_iterator, size_t) ` 멤버 함수를 제공해야 합니다.

읽기 전용 범위나 정적 크기의 행 유형(튜플, 배열, 구조체 등)을 가진 범위에서 작동하는 모델의 경우, 이 구현은 아무 작업도 수행하지 않고 즉시 false 를 반환합니다. 트리 모델의 경우 항상 이 규칙이 적용됩니다.

[override virtual] bool QRangeModel::removeRows(int row, int count, const QModelIndex &parent = {})

QAbstractItemModel::removeRows(int row, int count, const QModelIndex &parent)를 재구현합니다.

parent 에 있는 범위에서, 주어진 row 부터 시작하여 count 행을 제거합니다. 성공하면 true 를 반환하고, 그렇지 않으면 false 를 반환합니다.

참고: 범위는 동적으로 크기가 조정되어야 하며, erase(const_iterator, size_t) 멤버 함수를 제공해야 합니다.

읽기 전용이거나 크기가 정적으로 고정된 범위(예: 배열)에서 작동하는 모델의 경우, 이 구현은 아무 작업도 수행하지 않고 즉시 false 를 반환합니다.

[override virtual protected slot] void QRangeModel::resetInternalData()

QAbstractItemModel::resetInternalData()을 재구현합니다.

[override virtual] QHash<int, QByteArray> QRangeModel::roleNames() const

QAbstractItemModel::roleNames() const를 재구현합니다.

참고: ` QRangeModel `의 하위 클래스에서 이 함수를재정의할 수는 있지만, 이로 인해 속성의 동작이 깨질 수 있습니다.

참고: roleNames 속성에 대한getter 함수입니다.

참조: setRoleNames().

[override virtual] int QRangeModel::rowCount(const QModelIndex &parent = {}) const

QAbstractItemModel::rowCount(const QModelIndex &parent) const를 재구현합니다.

주어진 ` parent` 아래에 있는 행의 수를 반환합니다. 이는 유효하지 않은 ` parent ` 인덱스에 대한 루트 범위의 항목 수입니다.

parent 인덱스가 유효한 경우, 이 함수는 목록 및 테이블 범위를 다루는 모델에 대해서는 항상 0을 반환합니다. 트리의 경우, 이 함수는 트리 탐색 프로토콜의 childRows() 구현에서 반환하는 범위의 크기를 반환합니다.

columnCount(), insertRows(), hasChildren()도 참조하십시오 .

[override virtual] bool QRangeModel::setData(const QModelIndex &index, const QVariant &data, int role = Qt::EditRole)

QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role)를 재구현합니다.

index 에 있는 항목의 role 데이터를 data 로 설정합니다.

해당 index 의 항목 유형이 int, Qt::ItemDataRole 또는 QString 을 QVariant 으로 매핑하는 연관 컨테이너인 경우, data 는 role 로 지정된 키에 대해 해당 컨테이너에 저장됩니다.

항목이 가젯(gadget)이나 QObject 인 경우, data 는 roleNames() 매핑에서 role 항목과 일치하는 해당 항목의 속성에 기록됩니다. 이 함수는 속성이 발견되었고 data 에 저장된 값이 필요한 유형으로 변환될 수 있는 경우 true 를 반환하며, 그렇지 않은 경우 false 를 반환합니다.

그렇지 않은 경우, 이 구현은 Qt::DisplayRole 및 Qt::EditRole 에 대해 범위 내의 index 에 있는 항목에 data 의 값을 할당하고, true 을 반환합니다. 다른 역할의 경우, 이 구현은 false 을 반환합니다.

읽기 전용 범위에서 작동하는 모델이나, ` the C++ tuple protocol`을 구현하는 행 유형의 읽기 전용 열에서 작동하는 모델의 경우, 이 구현은 즉시 ` false `을 반환합니다.

data()도 참조하십시오 .

[override virtual] bool QRangeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &data, int role = Qt::EditRole)

QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)를 재구현합니다.

headerData()도 참조하십시오 .

[override virtual] bool QRangeModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &data)

QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)를 재구현합니다.

해당 index 의 항목 유형이 int 또는 Qt::ItemDataRole 에서 QVariant 로 매핑되는 연관 컨테이너인 경우, data 의 항목들은 해당 컨테이너에 저장됩니다. 연관 컨테이너가 QString 에서 QVariant 로 매핑되는 경우, role names 테이블에 매핑이 존재하는 data 의 값들만 저장됩니다.

항목 유형이 가젯(gadget)이나 QObject 의 하위 클래스인 경우, role name 와 일치하는 속성들은 data 에 있는 해당 값으로 설정됩니다.

data 에 항목이 없는 역할은 수정되지 않습니다.

복사 가능한 항목 유형의 경우, 이 구현은 트랜잭션 방식으로 이루어지며, data 의 모든 항목을 저장할 수 있으면 true를 반환합니다. 업데이트할 수 없는 항목이 하나라도 있으면, 원본 컨테이너는 전혀 수정되지 않으며 함수는 false를 반환합니다.

항목이 연관 컨테이너, 가젯 또는 QObject 의 하위 클래스가 아닌 경우, 이 함수는 기본 클래스 구현을 호출하며, 기본 클래스 구현은 data 의 각 항목에 대해 setData()를 호출합니다.

itemData(), setData(), Qt::ItemDataRole도 참조하십시오 .

[override virtual] QModelIndex QRangeModel::sibling(int row, int column, const QModelIndex &index) const

QAbstractItemModel::sibling(int row, int column, const QModelIndex &index) const를 재구현합니다.

index 에 있는 항목에 대해 row 및 column 에 위치한 형제 노드를 반환하며, 해당 위치에 형제 노드가 없는 경우 무효한 QModelIndex 을 반환합니다.

이 구현은 index 의 parent()을 순차적으로 탐색하는 방식보다 훨씬 빠릅니다.

index(), QModelIndex::row() 및 QModelIndex::column()도 참조하십시오 .

[override virtual] void QRangeModel::sort(int column, Qt::SortOrder order = Qt::AscendingOrder)

QAbstractItemModel::sort(int column, Qt::SortOrder order)를 재구현합니다.

column 내 항목들의 sortRole (기본값:Qt::DisplayRole )에 대한 데이터를 기반으로, 주어진 order 에 따라 기본 범위를 정렬합니다.

참고: 이 구현은 가능한 경우 C++ 범위의 멤버 함수 ` sort(Compare comp) `(예: ` std::list`에서와 같이)를 사용하며, 그렇지 않은 경우 범위가 임의 접근 이터레이터를 제공하는 경우 ` std::stable_sort() `를 사용합니다. 둘 다 사용할 수 없는 경우 구현은 아무 작업도 수행하지 않고 즉시 반환합니다.

참고: 항목에접근한다고 해서 data()의 오버라이드를 통해 데이터 읽기가 호출되지는 않습니다.

sortRole 및 QSortFilterProxyModel도 참조하십시오 .

[override virtual] QSize QRangeModel::span(const QModelIndex &index) const

QAbstractItemModel::span(const QModelIndex &index) const를 재구현합니다.

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.