Qtプログラミング: QListWidgetのアイテム操作を徹底解説
QListWidget
とは
QListWidget
は、アイテムのリストを表示・操作するためのウィジェットです。各アイテムは QListWidgetItem
オブジェクトとして表され、それぞれテキスト、アイコン、チェックボックスなどの情報を持つことができます。
QModelIndex
とは
QModelIndex
は、Qt のモデル/ビューアーキテクチャにおいて、モデル内のデータアイテムの位置(行、列、親インデックスなど)を示すための抽象的な概念です。QListWidget
の場合、これはリスト内の特定のアイテムを一意に特定するための「住所」のようなものと考えることができます。
QListWidget::itemFromIndex()
の役割
QListWidget::itemFromIndex(const QModelIndex &index)
関数は、次のような目的で使用されます。
-
QModelIndex
からQListWidgetItem
への変換:QListWidget
が内部的に使用するQModelIndex
オブジェクトから、開発者が直接操作したいQListWidgetItem
オブジェクトを取得するために使用します。 -
他のモデル/ビュークラスとの連携: 例えば、
QSortFilterProxyModel
のように、モデルのデータをソートしたりフィルタリングしたりするクラスを使用している場合、表示されているアイテムのQModelIndex
は元のモデルのインデックスとは異なることがあります。このような場合でも、QListWidget::itemFromIndex()
を使用することで、現在のQListWidget
上で表示されているアイテムに対応するQListWidgetItem
を正確に取得できます。 -
特定のアイテムのプロパティへのアクセス: 一度
QListWidgetItem
オブジェクトを取得すれば、そのアイテムのテキスト、アイコン、状態(チェックされているかなど)といったプロパティにアクセスしたり、変更したりすることができます。
例えば、QListWidget
で選択されたアイテムのテキストを取得したい場合、通常は selectedItems()
を使用しますが、もし何らかの理由で QModelIndex
から開始する必要がある場合、以下のように使用できます。
// 選択されているアイテムのモデルインデックスを取得 (例として、QItemSelectionModelから取得する場合)
QModelIndex selectedModelIndex = ui->listWidget->selectionModel()->currentIndex();
// QModelIndex から QListWidgetItem を取得
QListWidgetItem *item = ui->listWidget->itemFromIndex(selectedModelIndex);
if (item) {
// 取得した QListWidgetItem のテキストを表示
qDebug() << "Selected item text:" << item->text();
}
itemFromIndex が protected メンバーであるというコンパイルエラー
エラーメッセージ例
'itemFromIndex' is a protected member of 'QListWidget'
原因
QListWidget::itemFromIndex()
は protected
メンバー関数であるため、QListWidget
のサブクラス内から、または QListWidget
のフレンドクラスからしか直接呼び出すことができません。通常のアプリケーションコードで ui->listWidget->itemFromIndex(index)
のように直接呼び出そうとすると、このエラーが発生します。
トラブルシューティング
-
行番号からアイテムを取得する (item(int row))
QModelIndex
から行番号を取得できる場合(例:index.row()
)、QListWidget::item(int row)
関数を使って直接QListWidgetItem
を取得できます。これは、最も一般的な回避策であり、推奨される方法です。void MyWidget::on_listWidget_clicked(const QModelIndex &index) { // QModelIndex から行番号を取得し、item() 関数を使用 QListWidgetItem *item = ui->listWidget->item(index.row()); if (item) { qDebug() << "クリックされたアイテムのテキスト:" << item->text(); } }
-
QModelIndex を使わずに QListWidgetItem を取得する
多くの場合、QModelIndex
を直接扱う必要がないことがあります。例えば、QListWidget
のシグナル (例:itemClicked(QListWidgetItem*)
やcurrentItemChanged(QListWidgetItem*, QListWidgetItem*)
) を使用する場合、コールバック関数に直接QListWidgetItem
が渡されるため、itemFromIndex()
を使う必要はありません。 -
QListWidget のサブクラスを作成する
もしQListWidget
の特定の動作をカスタマイズする必要がある場合、QListWidget
を継承した独自のクラスを作成し、その中でitemFromIndex()
を呼び出すのが最も適切な方法です。
戻り値が nullptr になる
原因
itemFromIndex()
は、有効な QModelIndex
が与えられた場合にのみ QListWidgetItem
へのポインタを返します。以下のいずれかの状況で nullptr
を返す可能性があります。
- モデルが異なる
QListWidget
は内部的に独自のモデルを使用しています。もし別のモデル(例えば、QStandardItemModel
をQListView
で使用している場合)から取得したQModelIndex
をQListWidget::itemFromIndex()
に渡すと、期待通りに動作しない可能性があります。 - 無効な QModelIndex を渡した
QModelIndex
が、存在しない行や列を指している場合(例: アイテムが削除された後も古いインデックスを使用している、または範囲外のインデックスを使用している)。
トラブルシューティング
-
モデルとビューの整合性を確認する
QListWidget
を使用している場合、基本的にQListWidgetItem
を直接追加・削除するため、モデルとビューの不整合は起こりにくいですが、カスタムモデルを使用している場合は、モデルとビューの状態が同期しているかを確認してください。 -
イベントハンドラやシグナル/スロットの使用を見直す
QListWidget
から直接取得したQModelIndex
(例:clicked(const QModelIndex &index)
シグナルから渡されるもの) であれば通常は有効ですが、他のソースからQModelIndex
を取得している場合は、その有効性を慎重に確認する必要があります。 -
QModelIndex::isValid() で有効性を確認する
itemFromIndex()
を呼び出す前に、渡すQModelIndex
が有効であるかを確認します。void MyWidget::someFunction(const QModelIndex &index) { if (index.isValid()) { QListWidgetItem *item = ui->listWidget->itemFromIndex(index); if (item) { // アイテムが正常に取得された場合の処理 } else { qWarning() << "QListWidgetItem が nullptr を返しました。インデックスが有効なアイテムを指していません。"; } } else { qWarning() << "無効な QModelIndex が渡されました。"; } }
取得した QListWidgetItem のプロパティが期待通りでない
原因
itemFromIndex()
は正しく QListWidgetItem
を返しているが、そのアイテムのテキストやデータが期待通りではない場合があります。これは itemFromIndex()
自体の問題ではなく、通常は以下のいずれかが原因です。
- カスタムデータロールの扱いの誤り
QListWidgetItem::setData()
を使ってカスタムデータを保存している場合、取得する際に正しいデータロール(Qt::UserRole
など)を指定しているか確認してください。 - アイテムのデータが変更された後、UIが更新されていない
モデル内のデータが変更されたにもかかわらず、QListWidget
がその変更を反映していない可能性があります。明示的な更新が必要な場合(まれですが)、QListWidget::update()
やQListWidget::viewport()->update()
を試すことができます。ただし、通常はモデル/ビューの仕組みによって自動的に更新されます。 - 間違った QModelIndex を渡している
意図しないアイテムのQModelIndex
を渡してしまっている可能性があります。デバッガを使ってindex.row()
やindex.column()
を確認し、正しいアイテムを指しているかを確認してください。
トラブルシューティング
- シグナルとスロットの接続を確認する
イベントが発生した際に正しいQModelIndex
またはQListWidgetItem
がシグナルによって渡されているかを確認します。 - アイテムのデータ設定箇所を確認する
QListWidgetItem
が追加される際に、どのようなデータが設定されているか(テキスト、アイコン、カスタムデータなど)を確認します。 - デバッガで QModelIndex の内容を確認する
index.row()
やindex.data()
の値をデバッガで確認し、意図したアイテムのインデックスやデータが渡されているかを確認します。
Qt の QListWidget::itemFromIndex()
は protected
メンバー関数であるため、通常のアプリケーションコードから直接呼び出すことはできません。そのため、itemFromIndex()
を直接呼び出す例は、通常は QListWidget
のサブクラス内でしか機能しません。
しかし、現実的なアプリケーションでこの関数に相当する機能(QModelIndex
から QListWidgetItem
を取得する)が必要になるケースは存在します。ここでは、以下の2つのパターンでコード例を説明します。
QListWidget
のサブクラス内でitemFromIndex()
を使用する例 (この関数がprotected
であることを示す)itemFromIndex()
の代替としてitem(int row)
を使用する一般的な例 (より実用的で推奨される方法)
QListWidget のサブクラス内で itemFromIndex() を使用する例
この例では、MyListWidget
という QListWidget
のサブクラスを作成し、その中で itemFromIndex()
を使用する方法を示します。
mylistwidget.h
#ifndef MYLISTWIDGET_H
#define MYLISTWIDGET_H
#include <QListWidget>
#include <QDebug> // デバッグ出力用
class MyListWidget : public QListWidget
{
Q_OBJECT
public:
explicit MyListWidget(QWidget *parent = nullptr);
protected:
// QListWidget の clicked シグナルに対応するスロット
// このスロットは QModelIndex を受け取ります
void mousePressEvent(QMouseEvent *event) override; // 例としてクリックイベントをオーバーライド
signals:
// 新しいシグナルを定義して、MyListWidget の外に QListWidgetItem を渡す
void myItemClicked(QListWidgetItem *item);
private:
// ここで itemFromIndex() を呼び出すプライベート関数
// 実際に protected 関数を呼び出すのは、このクラスのメンバ関数からのみ
void processIndex(const QModelIndex &index);
};
#endif // MYLISTWIDGET_H
mylistwidget.cpp
#include "mylistwidget.h"
#include <QModelIndex> // QModelIndex を使用するために必要
#include <QMouseEvent> // QMouseEvent を使用するために必要
MyListWidget::MyListWidget(QWidget *parent)
: QListWidget(parent)
{
// 通常、QListWidget::clicked(const QModelIndex &index) シグナルを
// スロットに接続して使用しますが、ここでは例として mousePressEvent をオーバーライド
// connect(this, &QListWidget::clicked, this, &MyListWidget::processIndex);
}
void MyListWidget::mousePressEvent(QMouseEvent *event)
{
// クリックされた位置のモデルインデックスを取得
QModelIndex index = indexAt(event->pos());
if (index.isValid()) {
processIndex(index);
}
// 基底クラスのイベントハンドラを呼び出すことを忘れない
QListWidget::mousePressEvent(event);
}
void MyListWidget::processIndex(const QModelIndex &index)
{
// ここが重要: protected メンバーである itemFromIndex() を
// MyListWidget クラスのメンバ関数から呼び出す
QListWidgetItem *item = itemFromIndex(index);
if (item) {
qDebug() << "MyListWidget::processIndex() - アイテムのテキスト:" << item->text();
// 外部にアイテムを通知するためのシグナルを発行
emit myItemClicked(item);
} else {
qWarning() << "MyListWidget::processIndex() - QListWidgetItem が取得できませんでした。";
}
}
main.cpp (使用例)
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>
#include "mylistwidget.h" // 作成したカスタムウィジェット
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow window;
QWidget *centralWidget = new QWidget(&window);
QVBoxLayout *layout = new QVBoxLayout(centralWidget);
MyListWidget *myListWidget = new MyListWidget(centralWidget);
myListWidget->addItem("アイテム A");
myListWidget->addItem("アイテム B");
myListWidget->addItem("アイテム C");
layout->addWidget(myListWidget);
window.setCentralWidget(centralWidget);
// MyListWidget から発行されるカスタムシグナルに接続
QObject::connect(myListWidget, &MyListWidget::myItemClicked,
[](QListWidgetItem *clickedItem) {
qDebug() << "メインウィンドウで受信: クリックされたアイテムのテキスト:" << clickedItem->text();
});
window.show();
return a.exec();
}
説明
この例では、MyListWidget
クラス内で mousePressEvent
をオーバーライドし、クリックされた位置から QModelIndex
を取得しています。その QModelIndex
を processIndex
関数に渡し、processIndex
関数内で itemFromIndex()
を呼び出して対応する QListWidgetItem
を取得しています。MyListWidget
は QListWidget
のサブクラスなので、protected
メンバーである itemFromIndex()
を呼び出すことができます。
これが、QListWidget::itemFromIndex()
を直接呼び出すことなく、QModelIndex
から QListWidgetItem
を取得する最も一般的で推奨される方法です。QListWidget
の clicked(const QModelIndex &index)
シグナルなどを利用します。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QListWidget> // QListWidget を使用
#include <QModelIndex> // QModelIndex を使用
#include <QDebug> // デバッグ出力用
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
// QListWidget の clicked シグナルに対応するスロット
void on_listWidget_clicked(const QModelIndex &index);
private:
Ui::MainWindow *ui;
QListWidget *listWidget; // UIファイルを使わない場合
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QVBoxLayout>
// UI ファイルを使用しない場合のコンストラクタの例
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// UIをセットアップ
QWidget *centralWidget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(centralWidget);
setCentralWidget(centralWidget);
listWidget = new QListWidget(this);
layout->addWidget(listWidget);
// アイテムの追加
listWidget->addItem("リンゴ");
listWidget->addItem("バナナ");
listWidget->addItem("オレンジ");
// QListWidget の clicked シグナルをスロットに接続
// このシグナルはクリックされたアイテムの QModelIndex を渡します
connect(listWidget, &QListWidget::clicked, this, &MainWindow::on_listWidget_clicked);
}
// UI ファイルを使用する場合のコンストラクタの例(ui->listWidget_clicked を想定)
/*
#include "ui_mainwindow.h" // UIファイルが生成するヘッダ
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// アイテムの追加
ui->listWidget->addItem("リンゴ");
ui->listWidget->addItem("バナナ");
ui->listWidget->addItem("オレンジ");
// UIデザイナーで自動接続 (on_listWidget_clicked) されるか、手動で接続
// connect(ui->listWidget, &QListWidget::clicked, this, &MainWindow::on_listWidget_clicked);
}
*/
MainWindow::~MainWindow()
{
// delete ui; // UIファイルを使用する場合
}
// QListWidget の clicked シグナルに対応するスロット
void MainWindow::on_listWidget_clicked(const QModelIndex &index)
{
// QModelIndex から行番号 (row) を取得
int row = index.row();
// QListWidget::item(int row) を使って QListWidgetItem を取得
// item() は protected ではなく public なので、どこからでも呼び出せる
QListWidgetItem *clickedItem = listWidget->item(row); // UIファイルを使う場合は ui->listWidget->item(row);
if (clickedItem) {
qDebug() << "クリックされたアイテムのテキスト:" << clickedItem->text();
qDebug() << "データ (Qt::UserRole):" << clickedItem->data(Qt::UserRole).toString();
// 例えば、アイテムの背景色を変更する
clickedItem->setBackground(Qt::yellow);
} else {
// これは通常、index.isValid() が false の場合に発生
qWarning() << "アイテムが取得できませんでした。インデックスが無効な可能性があります。";
}
}
説明
この例では、QListWidget
の clicked(const QModelIndex &index)
シグナルを使用しています。このシグナルはクリックされたアイテムの QModelIndex
を提供します。
この QModelIndex
から index.row()
を呼び出すことで、アイテムの行番号を取得できます。
そして、QListWidget::item(int row)
関数(これは public
メンバー関数です)に行番号を渡すことで、対応する QListWidgetItem
を取得しています。この方法は itemFromIndex()
を直接使うよりもはるかに一般的で、推奨される方法です。
- QModelIndex から QListWidgetItem を取得する一般的な方法
QModelIndex::row()
で行番号を取得し、QListWidget::item(int row)
を呼び出すのが最も一般的で実用的な方法です。これはpublic
メンバー関数なので、どこからでも呼び出すことができます。 - QListWidget::itemFromIndex() を直接使う場合
QListWidget
のサブクラス内からのみ可能です。これは、QListWidget
の内部的な振る舞いをカスタマイズする際に役立ちます。
QListWidget::item(int row) を使用する(最も一般的で推奨される方法)
説明
QModelIndex
オブジェクトから行番号 (row
) を取得し、その行番号を使って QListWidget::item(int row)
関数を呼び出す方法です。QListWidget::item()
は public
メンバー関数なので、どこからでも安全に呼び出すことができます。
使用場面
QItemSelectionModel
などから取得したQModelIndex
に基づいてアイテムを取得する際。QListWidget::clicked(const QModelIndex &index)
シグナルやQListWidget::doubleClicked(const QModelIndex &index)
シグナルから渡されるQModelIndex
を処理する際。
コード例
#include <QApplication>
#include <QMainWindow>
#include <QListWidget>
#include <QVBoxLayout>
#include <QDebug>
#include <QModelIndex> // QModelIndex を使用するために必要
class MyWindow : public QMainWindow
{
Q_OBJECT
public:
MyWindow(QWidget *parent = nullptr) : QMainWindow(parent)
{
QListWidget *listWidget = new QListWidget(this);
setCentralWidget(listWidget);
listWidget->addItem("最初のアイテム");
listWidget->addItem("二番目のアイテム");
listWidget->addItem("三番目のアイテム");
listWidget->addItem("四番目のアイテム");
// QListWidget の clicked シグナルに接続
// このシグナルはクリックされたアイテムの QModelIndex を渡します
connect(listWidget, &QListWidget::clicked,
this, &MyWindow::onListItemClicked);
}
private slots:
void onListItemClicked(const QModelIndex &index)
{
if (index.isValid()) {
// QModelIndex から行番号を取得
int row = index.row();
// QListWidget::item(int row) を使って QListWidgetItem を取得
QListWidgetItem *item = qobject_cast<QListWidget*>(sender())->item(row);
// あるいは、メンバ変数として QListWidget を持っている場合は直接アクセス
// QListWidgetItem *item = this->myListWidget->item(row);
if (item) {
qDebug() << "クリックされたアイテムのテキスト (item(row) 経由):" << item->text();
item->setBackground(Qt::yellow); // 例として背景色を変更
} else {
qWarning() << "アイテムが取得できませんでした。";
}
} else {
qWarning() << "無効な QModelIndex が渡されました。";
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWindow w;
w.show();
return a.exec();
}
#include "main.moc" // moc ファイルのインクルード(Qt Creator以外で手動コンパイルする場合)
利点
- ほとんどの一般的なユースケースに対応できる。
public
な関数なので、どこからでも呼び出せる。- 最も直接的で理解しやすい。
QListWidget::currentItem() または QListWidget::selectedItems() を使用する
説明
特定のアイテムが選択されている場合や、現在フォーカスを持っているアイテムを取得したい場合に非常に便利です。QModelIndex
を介さずに直接 QListWidgetItem
を取得できます。
使用場面
- コンテキストメニューの表示など、選択状態に依存する操作。
- 現在ハイライトされているアイテムの情報を取得したい場合。
- ユーザーが単一または複数のアイテムを選択した後に、そのアイテムを操作したい場合。
コード例
#include <QApplication>
#include <QMainWindow>
#include <QListWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
#include <QMenu>
#include <QMessageBox>
class MyWindow : public QMainWindow
{
Q_OBJECT
public:
MyWindow(QWidget *parent = nullptr) : QMainWindow(parent)
{
QWidget *centralWidget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(centralWidget);
setCentralWidget(centralWidget);
listWidget = new QListWidget(this);
listWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); // 複数選択を可能にする
layout->addWidget(listWidget);
listWidget->addItem("アイテム 1");
listWidget->addItem("アイテム 2");
listWidget->addItem("アイテム 3");
listWidget->addItem("アイテム 4");
QPushButton *buttonCurrent = new QPushButton("現在のアイテムを表示", this);
layout->addWidget(buttonCurrent);
connect(buttonCurrent, &QPushButton::clicked,
this, &MyWindow::showCurrentItem);
QPushButton *buttonSelected = new QPushButton("選択されたアイテムを表示", this);
layout->addWidget(buttonSelected);
connect(buttonSelected, &QPushButton::clicked,
this, &MyWindow::showSelectedItems);
// コンテキストメニューの例
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(listWidget, &QListWidget::customContextMenuRequested,
this, &MyWindow::showContextMenu);
}
private slots:
void showCurrentItem()
{
QListWidgetItem *currentItem = listWidget->currentItem();
if (currentItem) {
qDebug() << "現在のアイテム (currentItem()):" << currentItem->text();
} else {
qDebug() << "現在のアイテムはありません。";
}
}
void showSelectedItems()
{
QList<QListWidgetItem *> selectedItems = listWidget->selectedItems();
if (!selectedItems.isEmpty()) {
qDebug() << "選択されたアイテム (selectedItems()):";
for (QListWidgetItem *item : selectedItems) {
qDebug() << " -" << item->text();
}
} else {
qDebug() << "選択されたアイテムはありません。";
}
}
void showContextMenu(const QPoint &pos)
{
QListWidgetItem *clickedItem = listWidget->itemAt(pos); // ここも代替方法!
if (clickedItem) {
QMenu contextMenu(this);
QAction *deleteAction = contextMenu.addAction("削除");
QAction *renameAction = contextMenu.addAction("名前変更");
QAction *selectedAction = contextMenu.exec(listWidget->mapToGlobal(pos));
if (selectedAction == deleteAction) {
QMessageBox::information(this, "アクション", clickedItem->text() + " を削除します。");
delete listWidget->takeItem(listWidget->row(clickedItem)); // アイテムを削除
} else if (selectedAction == renameAction) {
QMessageBox::information(this, "アクション", clickedItem->text() + " の名前を変更します。");
// 実際にはQInputDialogなどを使って名前変更処理を実装
}
}
}
private:
QListWidget *listWidget;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWindow w;
w.show();
return a.exec();
}
#include "main.moc"
利点
- ユーザーのインタラクション(選択)に直接関連する処理に適している。
- 非常に直感的で、コードが簡潔になる。
QListWidget::itemAt(const QPoint &p) を使用する
説明
ビューポート内の特定の座標 (QPoint
) にある QListWidgetItem
を取得します。主に、マウスイベント(例: mousePressEvent
、customContextMenuRequested
)やドラッグ&ドロップ操作で、ユーザーがクリックまたはドラッグしている位置のアイテムを特定したい場合に使用します。
使用場面
- マウスホバーイベントで、マウスカーソル下のアイテム情報を表示する。
- カスタムのドラッグ&ドロップ処理で、ドロップ先のアイテムを特定する。
- 右クリックメニュー(コンテキストメニュー)を表示する際に、クリックされたアイテムを特定する。
コード例
上記の「選択されたアイテムを表示」の例の showContextMenu
関数内で listWidget->itemAt(pos)
を使用しています。
// ... (上記コードの続き)
void showContextMenu(const QPoint &pos)
{
// ビューポート座標 pos にあるアイテムを取得
QListWidgetItem *clickedItem = listWidget->itemAt(pos);
if (clickedItem) {
QMenu contextMenu(this);
QAction *deleteAction = contextMenu.addAction("削除");
QAction *renameAction = contextMenu.addAction("名前変更");
// グローバル座標に変換してメニューを表示
QAction *selectedAction = contextMenu.exec(listWidget->mapToGlobal(pos));
if (selectedAction == deleteAction) {
qDebug() << clickedItem->text() << "を削除";
// 削除処理...
} else if (selectedAction == renameAction) {
qDebug() << clickedItem->text() << "の名前を変更";
// 名前変更処理...
}
}
}
// ...
利点
- マウスイベントと組み合わせて非常に強力なインタラクションを提供できる。
- 物理的なスクリーン上の位置からアイテムを特定できる。
アイテムのデータロールを利用する (QListWidgetItem::data(), Qt::UserRole)
説明
直接 QListWidgetItem
を取得する方法ではありませんが、アイテムに関連付けられたカスタムデータを取得・操作したい場合に非常に重要です。QListWidgetItem
には、表示されるテキストやアイコン以外にも、任意のデータを保存できます。
使用場面
- アイテム選択後、そのカスタムデータを元に次の処理を行いたい場合。
コード例
#include <QApplication>
#include <QMainWindow>
#include <QListWidget>
#include <QVBoxLayout>
#include <QDebug>
#include <QVariant> // QVariant を使用するために必要
class MyWindowWithData : public QMainWindow
{
Q_OBJECT
public:
MyWindowWithData(QWidget *parent = nullptr) : QMainWindow(parent)
{
QListWidget *listWidget = new QListWidget(this);
setCentralWidget(listWidget);
// アイテムにカスタムデータを追加
QListWidgetItem *item1 = new QListWidgetItem("商品 A");
item1->setData(Qt::UserRole, QVariant(101)); // 商品ID
listWidget->addItem(item1);
QListWidgetItem *item2 = new QListWidgetItem("商品 B");
item2->setData(Qt::UserRole, QVariant(102)); // 商品ID
listWidget->addItem(item2);
QListWidgetItem *item3 = new QListWidgetItem("商品 C");
item3->setData(Qt::UserRole, QVariant(103)); // 商品ID
listWidget->addItem(item3);
connect(listWidget, &QListWidget::itemClicked,
this, &MyWindowWithData::onListItemClicked);
}
private slots:
void onListItemClicked(QListWidgetItem *item)
{
if (item) {
qDebug() << "クリックされたアイテムのテキスト:" << item->text();
// カスタムデータ (Qt::UserRole) を取得
int productId = item->data(Qt::UserRole).toInt();
qDebug() << "関連する商品ID:" << productId;
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWindowWithData w;
w.show();
return a.exec();
}
#include "main.moc"
- モデル/ビューの概念に沿ったデータの管理ができる。
- 複雑な情報を各アイテムに効率的に格納できる。
- 表示データと内部データを分離できる。