我正在尝试对QTableView
中的行进行拖放式重新排序。
该操作实际上需要对基础数据进行重新排序,因此对垂直标题行进行重新排序似乎不是一个好的解决方案。
我改为选择底层模型来处理此问题,方法是在其mimeData
函数中提供行索引,并在dropMimeData
中接受此列表。在dropMimeData
函数中,除了移动基础数据之外,我还使用beginMoveRows
和endMoveRows
可视地移动单个行。这种方法似乎有效,只有一个缺点:我调用endMoveRows
时,QTableView
的水平标题将其所有节大小重置为默认值。
我是否错过了我需要做的事情,或者这是Qt中的错误(甚至是预期的行为)吗?还有其他方法可以处理拖放的重新排序吗?
以下是显示相同行为的简化代码:
class Model: public QAbstractTableModel
{
public:
Model():
m_Items({"A", "B", "C", "D", "E"})
{
}
virtual QVariant data(const QModelIndex & a_Parent, int a_Role) const override
{
return QString("%1 - %2").arg(m_Items[a_Parent.row()]).arg(a_Parent.column());
}
virtual int rowCount(const QModelIndex & a_Parent) const override
{
return m_Items.count();
}
virtual int columnCount(const QModelIndex & a_Parent) const override
{
return 4;
}
void moveNow()
{
// Moves the last row as the 3rd row:
auto count = m_Items.count();
beginMoveRows(QModelIndex(), count, count, QModelIndex(), 2);
m_Items.insert(2, m_Items.last());
m_Items.pop_back();
endMoveRows();
}
protected:
QStringList m_Items;
};
static Model g_Model;
MainWindow::MainWindow(QWidget * parent):
QMainWindow(parent),
ui(new Ui::MainWindow)
{
// "ui" created by QtCreator, has a "tableView" and a "pushButton"
ui->setupUi(this);
ui->tableView->setModel(&g_Model);
ui->tableView->horizontalHeader()->resizeSection(0, 200);
ui->tableView->horizontalHeader()->resizeSection(1, 100);
ui->tableView->horizontalHeader()->resizeSection(2, 50);
ui->tableView->horizontalHeader()->resizeSection(3, 80);
connect(ui->pushButton, &QPushButton::clicked,
[this]()
{
// Outputs 200 on first click
qDebug() << ui->tableView->horizontalHeader()->sectionSize(0);
g_Model.moveNow();
// Outputs 100
qDebug() << ui->tableView->horizontalHeader()->sectionSize(0);
}
);
}
答案 0 :(得分:0)
我发现在移动操作之前调用emit layoutAboutToBeChanged()
可以解决此问题:
void moveNow()
{
emit layoutAboutToBeChanged();
auto count = m_Items.count();
beginMoveRows(QModelIndex(), count, count, QModelIndex(), 2);
m_Items.insert(2, m_Items.last());
m_Items.pop_back();
endMoveRows();
}
这似乎与beginMoveRows
的文档矛盾,这表明它是调用此函数的替代。此外,在emit layoutChanged()
之后必须不匹配endMoveRows
,否则,列将再次重置。
这一切使我相信这是Qt中的实际错误。