如何在 QListWidget Qt 中锁定一个项目
How to lock an item in QListWidget Qt
是否可以锁定 QListWidget 中的某个项目,例如当我按下一个按钮时,该项目保持选中状态?
我试图查找它但我失败了
I really hope you can provide me with an example, since I am just a beginner
是的,我可以。我们开始吧:
testQListWidgetLockSelection.cc
:
#include <set>
#include <QtWidgets>
class ListWidget: public QListWidget {
public:
using QListWidget::QListWidget;
virtual ~ListWidget() = default;
void lockSelection(bool lock);
virtual void selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected) override;
private:
bool _lockSel = false;
std::set<int> _selLocked;
bool _lockResel = false;
struct LockGuard {
bool &lock;
LockGuard(bool &lock): lock(lock) { lock = true; }
~LockGuard() { lock = false; }
};
};
void ListWidget::lockSelection(bool lock)
{
_lockSel = lock;
if (_lockSel) {
// store selected indices
for (const QModelIndex &qMI : selectedIndexes()) _selLocked.insert(qMI.row());
} else _selLocked.clear();
}
void ListWidget::selectionChanged(
const QItemSelection& selected, const QItemSelection& deselected)
{
if (_lockSel && !_lockResel) {
const LockGuard lock(_lockResel);
QItemSelection reselect;
for (int row : _selLocked) {
const QModelIndex qMI = model()->index(row, 0);
reselect.select(qMI, qMI);
}
selectionModel()->select(reselect, QItemSelectionModel::Select);
}
}
void populate(QListWidget& qLstView)
{
for (int i = 1; i <= 20; ++i) {
qLstView.addItem(QString("Item %1").arg(i));
}
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.resize(640, 480);
qWinMain.setWindowTitle("Lock Selection Demo");
QVBoxLayout qVBox;
QCheckBox qTglLockSel("Lock Selection");
qVBox.addWidget(&qTglLockSel, false);
ListWidget qLstView;
qLstView.setSelectionMode(ListWidget::ExtendedSelection);
qVBox.addWidget(&qLstView, true);
qWinMain.setLayout(&qVBox);
qWinMain.show();
// install signal handlers
QObject::connect(&qTglLockSel, &QCheckBox::toggled,
&qLstView, &ListWidget::lockSelection);
// fill GUI with sample data
populate(qLstView);
// runtime loop
return app.exec();
}
演示:
注:
这个示例有一个弱点:它没有考虑在锁定选择后可以插入或删除项目。
为了加强这一点,成员函数 rowsInserted() and rowsAboutToBeRemoved() 也必须被覆盖,以分别更正 ListWidget::_selLocked
中的索引。
是否可以锁定 QListWidget 中的某个项目,例如当我按下一个按钮时,该项目保持选中状态? 我试图查找它但我失败了
I really hope you can provide me with an example, since I am just a beginner
是的,我可以。我们开始吧:
testQListWidgetLockSelection.cc
:
#include <set>
#include <QtWidgets>
class ListWidget: public QListWidget {
public:
using QListWidget::QListWidget;
virtual ~ListWidget() = default;
void lockSelection(bool lock);
virtual void selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected) override;
private:
bool _lockSel = false;
std::set<int> _selLocked;
bool _lockResel = false;
struct LockGuard {
bool &lock;
LockGuard(bool &lock): lock(lock) { lock = true; }
~LockGuard() { lock = false; }
};
};
void ListWidget::lockSelection(bool lock)
{
_lockSel = lock;
if (_lockSel) {
// store selected indices
for (const QModelIndex &qMI : selectedIndexes()) _selLocked.insert(qMI.row());
} else _selLocked.clear();
}
void ListWidget::selectionChanged(
const QItemSelection& selected, const QItemSelection& deselected)
{
if (_lockSel && !_lockResel) {
const LockGuard lock(_lockResel);
QItemSelection reselect;
for (int row : _selLocked) {
const QModelIndex qMI = model()->index(row, 0);
reselect.select(qMI, qMI);
}
selectionModel()->select(reselect, QItemSelectionModel::Select);
}
}
void populate(QListWidget& qLstView)
{
for (int i = 1; i <= 20; ++i) {
qLstView.addItem(QString("Item %1").arg(i));
}
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.resize(640, 480);
qWinMain.setWindowTitle("Lock Selection Demo");
QVBoxLayout qVBox;
QCheckBox qTglLockSel("Lock Selection");
qVBox.addWidget(&qTglLockSel, false);
ListWidget qLstView;
qLstView.setSelectionMode(ListWidget::ExtendedSelection);
qVBox.addWidget(&qLstView, true);
qWinMain.setLayout(&qVBox);
qWinMain.show();
// install signal handlers
QObject::connect(&qTglLockSel, &QCheckBox::toggled,
&qLstView, &ListWidget::lockSelection);
// fill GUI with sample data
populate(qLstView);
// runtime loop
return app.exec();
}
演示:
注:
这个示例有一个弱点:它没有考虑在锁定选择后可以插入或删除项目。
为了加强这一点,成员函数 rowsInserted() and rowsAboutToBeRemoved() 也必须被覆盖,以分别更正 ListWidget::_selLocked
中的索引。