qt - 当有委托时,使 QTableView 的 Key_Up 和 Key_Tab 行为相同
问题描述
我有一个 QTable,其中一列有时,即某些行,有一个 QLineEdit 类型的委托编辑器。用户只能选择整行。当一个 QLineEdit 具有焦点并且用户按下 Key_Up/Key_Down 时,上一行/下一行被选中,并且上一个/下一个 QLineEdit 自动获得焦点。如何为选项卡获得相同的行为?我试图在表格视图中捕获关键事件,即
void ScalarTableTableView::keyPressEvent(QKeyEvent *event)
{
// Change tab to arrow up/down to be able to move to next row with one key.
if(event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab)
{
QKeyEvent newEvent(event->type(),
event->key() == Qt::Key_Tab ? Qt::Key_Down : Qt::Key_Up,
event->modifiers(),
event->nativeScanCode(),
event->nativeModifiers(),
event->nativeVirtualKey(),
event->text(),
event->isAutoRepeat(),
event->count());
event->accept();
MoveBetweenViewsWithDragAndDropTableView::keyPressEvent(&newEvent);
}
else
{
MoveBetweenViewsWithDragAndDropTableView::keyPressEvent(event);
}
}
这适用于选择上一行/下一行,但 QLineEdit 没有获得焦点。我需要手动设置焦点吗?如果是这样,我怎样才能获得某一行的委托 QLineEdit?这似乎隐藏在 QAbstractItemView 的私有部分中。
经过测试的解决方案不起作用:
void ScalarTableTableView::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab)
{
QModelIndex newCurrent = moveCursor(event->key() == Qt::Key_Tab ? MoveDown: MoveUp, event->modifiers());
QItemSelectionModel::SelectionFlags command = selectionCommand(newCurrent, event);
selectionModel()->setCurrentIndex(newCurrent, command);
return;
}
QTableView::keyPressEvent(event);
}
在 QLineEdit 中捕获制表键不起作用 - 它永远不会到达那里。
调用 QAbstractItemView::edit 也不起作用。
最小可重现示例
主文件
#include "delegate.h"
#include "MyTableModel.h"
#include "MyTableView.h"
#include <QApplication>
#include <QHeaderView>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyTableModel model;
MyTableView tableView;
tableView.setModel(&model);
tableView.setSelectionBehavior(QAbstractItemView::SelectRows);
SpinBoxDelegate delegate;
tableView.setItemDelegate(&delegate);
for (int i = 0; i < 2; i++)
{
tableView.openPersistentEditor(model.createIndexValue(i, 1));
}
tableView.horizontalHeader()->setStretchLastSection(true);
tableView.setWindowTitle(QObject::tr("Delegate"));
tableView.show();
return app.exec();
}
委托人.h
#ifndef DELEGATE_H
#define DELEGATE_H
#include <QStyledItemDelegate>
class SpinBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
SpinBoxDelegate(QObject *parent = nullptr);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
};
#endif
委托.cpp
#include "delegate.h"
#include <QLineEdit>
SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QLineEdit *editor = new QLineEdit(parent);
return editor;
}
void SpinBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
int value = index.model()->data(index, Qt::EditRole).toInt();
QLineEdit *edit = static_cast<QLineEdit*>(editor);
edit->setText(std::to_string(value).c_str());
}
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QLineEdit *edit = static_cast<QLineEdit*>(editor);
int value = stoi(edit->text().toStdString());
model->setData(index, value, Qt::EditRole);
}
void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
MyTableModel.h
#ifndef MYTABLEMODEL_H
#define MYTABLEMODEL_H
#include <QAbstractTableModel>
class MyTableModel : public QAbstractTableModel
{
public:
explicit MyTableModel(QObject *parent = nullptr);
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QModelIndex createIndexValue(int row, int column) {return createIndex(row, column);}
};
#endif // MYTABLEMODEL_H
MyTableModel.cpp
#include "MyTableModel.h"
MyTableModel::MyTableModel(QObject *parent) : QAbstractTableModel(parent)
{
}
int MyTableModel::columnCount(const QModelIndex &parent) const
{
return 2;
}
QVariant MyTableModel::data(const QModelIndex &index, int role) const
{
return std::to_string((index.column() + 1) * (index.row() + 1)).c_str();
}
Qt::ItemFlags MyTableModel::flags(const QModelIndex &index) const
{
return Qt::ItemNeverHasChildren|Qt::ItemIsEnabled|Qt::ItemIsSelectable;
}
int MyTableModel::rowCount(const QModelIndex &parent) const
{
return 2;
}
MyTableView.h
#ifndef MYTABLEVIEW_H
#define MYTABLEVIEW_H
#include <QTableView>
class MyTableView : public QTableView
{
public:
MyTableView();
protected:
void keyPressEvent(QKeyEvent *event) override;
};
#endif // MYTABLEVIEW_H
MyTableView.cpp
#include "MyTableView.h"
#include <QKeyEvent>
MyTableView::MyTableView()
{
}
void MyTableView::keyPressEvent(QKeyEvent *event)
{
// Change tab to arrow up/down to be able to move to next row with one key.
if(event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab)
{
QKeyEvent newEvent(event->type(),
event->key() == Qt::Key_Tab ? Qt::Key_Down : Qt::Key_Up,
event->modifiers(),
event->nativeScanCode(),
event->nativeModifiers(),
event->nativeVirtualKey(),
event->text(),
event->isAutoRepeat(),
event->count());
//QCoreApplication::sendEvent(this, &newEvent);
event->accept();
QTableView::keyPressEvent(&newEvent);
}
else
{
QTableView::keyPressEvent(event);
}
}
解决方案
推荐阅读
- node.js - 遍历列表并运行 gulp 任务
- ios - 尝试使用 Swift 5 传回数据时,iOS 委托为零
- python - sklearn:调用 naive_bayes.MultinomialNB(
- python - 查找“bytes”和“str”之间的所有比较
- oracle - Deno:如何连接到 oracle 数据库?
- java - 当 jwt 令牌无效时,主体对象为空
- c - C 双重赋值在运行时不正确(但使用 printf 正确)
- python - 如何以元组的形式将打印的语句添加到字典中?
- java - 获取小数点后第n位
- vim - How to cycle through vim marks