【问题标题】:Slot called twice qt插槽调用了两次 qt
【发布时间】:2018-06-18 04:58:49
【问题描述】:

我在停靠小部件中有一个可编辑的列表视图。我想跟踪用户编辑之前的数据和用户编辑之后的数据。完整的相关代码是:

void MainWindow :: createDock()
{
    //initialize dockWidget
    QDockWidget *dock = new QDockWidget("Tags", this);
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    dock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);

//widget to store all widgets placed inside dock because dock cannot set layout but can set widget
QWidget *tags = new QWidget(dock);

//initiazlize treeViewModel
listViewModel = new QSqlTableModel(this);
listViewModel->setTable("tags");
listViewModel->select();
listViewModel->setHeaderData(0, Qt::Horizontal, "Tags");

//set the model for treeView
listView = new QListView(dock);
listView->setModel(listViewModel);

connect(listView, &QListView::doubleClicked, this, &MainWindow::onListViewDoubleClicked, Qt::UniqueConnection);
connect(listViewModel, &QSqlTableModel::dataChanged, this, &MainWindow::onLVDataChanged, Qt::UniqueConnection);

//add treeView to the dock
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(listView);
tags->setLayout(layout);

//add the dock widget to the main window and show it
dock->setWidget(tags);
this->addDockWidget(Qt::LeftDockWidgetArea, dock);
//dock->show();
}

void MainWindow :: onLVDataChanged(const QModelIndex& index, const QModelIndex& index2, const QVector<int> & roles)
{
    QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
    QMessageBox::information(this, "", metaMethod.name());

afterUpdate = index.data().toString();

//do somethings

beforeUpdate = "";
afterUpdate = "";
}

void MainWindow :: onListViewDoubleClicked(const QModelIndex &index)
{
    QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
    QMessageBox::information(this, "", metaMethod.name());

beforeUpdate = index.data().toString();
}

我这样做: 我双击一个项目以对其进行编辑。 onDoubleClick() 只被调用一次(见于 QMessageBox)。我在现有数据中添加了一个空格(在我的情况下是“小说”,我将其更改为“小说”)。但是,在我按下回车后,dataChanged() 被调用了两次(再次通过 QMessageBox 看到)。

我没有明确发出信号。它仅由模型发出。

【问题讨论】:

  • 你检查过信号发送的角色了吗? void QAbstractItemModel::dataChanged(const QModelIndex &amp;topLeft, const QModelIndex &amp;bottomRight, const QVector&lt;int&gt; &amp;roles = ...)
  • 现在? @eyllanesc
  • 你做了什么动作来触发信号?请改进您的示例并提供一个不错的 MCVE
  • 问题出在 onListViewDoubleClicked 还是 onLVDataChanged?

标签: c++ qt qt5 qlistview qsqltablemodel


【解决方案1】:

问题是由编辑策略引起的,默认是QSqlTableModel::OnRowChange,这期望行被改变,发出一个更新项目的信号,另一个更新整行,如果我们使用可以很容易地看到以下:

void MainWindow::onListViewDoubleClicked(const QModelIndex &index)
{
    qDebug()<<__FUNCTION__<<index;
}

void MainWindow::onLVDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    qDebug()<<__FUNCTION__<<topLeft<<bottomRight<<roles<<topLeft.data();
}

输出:

onListViewDoubleClicked QModelIndex(1,0,0x0,QSqlTableModel(0x562940043670))
onLVDataChanged QModelIndex(1,0,0x0,QSqlTableModel(0x562940043670)) QModelIndex(1,0,0x0,QSqlTableModel(0x562940043670)) QVector() QVariant(QString, "tag2 ")
onLVDataChanged QModelIndex(1,0,0x0,QSqlTableModel(0x562940043670)) QModelIndex(1,2,0x0,QSqlTableModel(0x562940043670)) QVector() QVariant(QString, "tag2 ")

解决方法是将编辑策略改为QSqlTableModel::OnManualSubmit

...
listViewModel = new QSqlTableModel(this);
listViewModel->setTable("tags");
listViewModel->setEditStrategy(QSqlTableModel::OnManualSubmit); // <--
listViewModel->select();
listViewModel->setHeaderData(0, Qt::Horizontal, "Tags");
...

【讨论】:

  • 我不知何故预计问题可能是由于编辑策略引起的。非常感谢。它有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多