C++ 如何避免在编辑时删除树模型信息?
早上好。我终于创建了一个treeconfig程序来读取一个txt,然后在界面中编辑它,然后保存它,但是我遇到了一个问题 我知道有一个treemodel示例是可编辑的(),但这个示例没有使用libconfig.h++ 我决定在linux中使用libconfig.h++是因为我可以过滤值(int/string/…)中出现的信息类型,因为在另一个没有libconfig的示例中,它使用qVariant,并接受所有类型的输入 因此,即使与另一个例子相比,我也无法做到以下几点: 我的问题是,当我试图编辑一个值时,其中的信息会消失,如果我在该值之外单击,它将变为0。我怎样才能避免这两件事呢?例如,我想在中间编辑一个字符串,或者只是在点击错误或某事时不删除信息。 下图显示了编辑confTimeout值的尝试。请注意,当单击进入编辑模式时,其中的文本将消失,而当单击不对焦时,文本将设置为0 mainwindow.cppC++ 如何避免在编辑时删除树模型信息?,c++,qt,qt5,qtreeview,libconfig,C++,Qt,Qt5,Qtreeview,Libconfig,早上好。我终于创建了一个treeconfig程序来读取一个txt,然后在界面中编辑它,然后保存它,但是我遇到了一个问题 我知道有一个treemodel示例是可编辑的(),但这个示例没有使用libconfig.h++ 我决定在linux中使用libconfig.h++是因为我可以过滤值(int/string/…)中出现的信息类型,因为在另一个没有libconfig的示例中,它使用qVariant,并接受所有类型的输入 因此,即使与另一个例子相比,我也无法做到以下几点: 我的问题是,当我试图编辑一个
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextStream>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
void MainWindow::setConfig(libconfig::Config *config)
{
tm = std::make_unique<TreeModel>(config, this);
ui->treeView->setModel(tm.get());
}
MainWindow::~MainWindow()
{
delete ui;
}
/*
void MainWindow::on_treeView_activated(const QModelIndex &index)
{
QString val = ui->treeView->model()->data(index).toString();
ui->lineEdit->setText(val);
}
*/
void MainWindow::on_pushButton_clicked()
{
tm->saveSettings();
}
有什么想法吗?我认为问题在于,根据您提供的代码,您的
TreeModel::data()
函数在请求的角色不是显示角色时总是返回空数据。这意味着,如果将节点置于编辑模式,编辑器(行编辑)将不显示任何内容。移动焦点时,编辑器将关闭并将其空值设置为模型。这就是为什么你会得到这个“0”
要修复此行为,您需要在编辑模式下公开与在显示模式下相同的数据,即您的代码应该如下所示:
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
// Returns the same data both in display and edit modes.
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
return item->data(index.column());
}
return QAbstractItemModel::data(index, role);
}
QVariant树模型::数据(常量QModelIndex&index,int角色)常量
{
如果(!index.isValid())
返回QVariant();
//在显示和编辑模式下返回相同的数据。
如果(角色==Qt::DisplayRole | |角色==Qt::EditRole)
{
TreeItem*item=static_cast(index.internalPointer());
返回项目->数据(index.column());
}
返回qabstractemmodel::数据(索引、角色);
}
QVariant。。。也可以。请问如果(role!=Qt::EditRole)返回false,那么有什么用代码>在TreeModel::setData()
中?另外,提供的示例使用if(role!=Qt::DisplayRole&&role!=Qt::EditRole)返回QVariant()代码>。在您的TreeModel::data()
,角色中!=已删除Qt::EditRole
。对此也有解释吗?你可以在github上发布你的项目,这样就可以轻松地测试你的代码。我已经尝试过你的例子@vahancho,但它仍然不起作用。我已经更新了显示问题的主要注释。它应该是&&而不是这个| |!!现在它起作用了
#include "treemodel.h"
#include "treeitem.h"
#include <QFile>
#include <libconfig.h++>
#include <QDateTime>
TreeModel::TreeModel(libconfig::Config *config, QObject *parent)
: QAbstractItemModel{parent}, m_rootSetting{std::make_unique<TreeItem>(
&(config->getRoot()), nullptr)}, m_config{config}
{
}
TreeModel::~TreeModel()
{
}
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->data(index.column());
}
bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
if (role != Qt::EditRole)
return false;
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
return item->setData(value);
}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
//return Qt::NoItemFlags;
return 0;
//return QAbstractItemModel::flags(index);
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
}
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
return QVariant{};
switch (section) {
case 0:
return "Name";
case 1:
return "Value";
default:
return QVariant{};
}
}
QModelIndex TreeModel::index(int row, int column,
const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
TreeItem *parentItem;
if (!parent.isValid())
parentItem = m_rootSetting.get();
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *childItem = static_cast<TreeItem *>(index.internalPointer());
TreeItem *parentItem = childItem->parentItem();
if (parentItem == m_rootSetting.get())
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int TreeModel::rowCount(const QModelIndex &parent) const
{
TreeItem *parentItem;
if (parent.column() > 0)
return 0;
if (!parent.isValid())
parentItem = m_rootSetting.get();
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
return parentItem->childCount();
}
int TreeModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
else
return m_rootSetting->columnCount();
}
bool TreeModel::saveSettings(QString filename) const
{
if (filename.isEmpty())
filename = QString::fromLocal8Bit(m_config->getRoot().getSourceFile());
QString today = QDateTime::currentDateTime().toString("_yyyy.MM.dd_hh:mm");
QFile::copy(filename, filename+today+".backup");
try {
m_config->writeFile(filename.toLocal8Bit().constData());
} catch (...) {
return false;
}
return true;
}
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant();
TreeItem *item = getItem(index);
return item->data(index.column());
}
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
// Returns the same data both in display and edit modes.
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
return item->data(index.column());
}
return QAbstractItemModel::data(index, role);
}