现在,我可以在函数QTableWidget
中处理eventFilter()
中的所有按键操作(在构造函数中调用myTable->viewport()->installEventFilter(this);
之后)。
唯一不起作用的地方是编辑时的可编辑单元格(因为它会抓取所有按键)。要解决此问题,我无法为表格中的每个项目调用installEventFilter()
,因为这些项目不是QObject
s(而且我也无法使用connect
来处理我的处理按键)。
我唯一的解决方案是将QLineEdit
放在这些单元格中,并使用事件过滤器在编辑时捕获按键。但是,仅使用标准物品可以解决它吗? (即仅QTableWidgetItem
带有标记Qt::ItemIsEditable
)
我也可以为grabKeyboard()
致电QTableWidget
。在这种情况下,我将按下所有按键(即使在用户编辑单元格时),但它会阻止编辑框(即用户无法输入任何内容)。可能是在为表格调用grabKeyboard()
后修复损坏的编辑框?
答案 0 :(得分:2)
这很容易实现。只是子类QStyledItemDelegate
覆盖createEditor
方法,如下所示:
QWidget *AlterEditorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
QWidget *result = QStyledItemDelegate::createEditor(parent, option, index);
result->installEventFilter(new YourEventFilter(result));
return result;
}
替换QTableWidget的委托。
甚至更好的是继承创建代理类,它接受原始的QAbstractItemDelegate
(更多的写作,但更通用,可以与其他修改组合)。
AlterEditorProxyDelegate::AlterEditorProxyDelegate(QAbstractItemDelegate *original, QObject *parent)
: QAbstractItemDelegate(parent)
, original(original)
{}
QWidget *AlterEditorProxyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
QWidget *result = original->createEditor(parent, option, index);
result->installEventFilter(new YourEventFilter(result));
return result;
}
// other methods which invokes respective methods for `original` style.
答案 1 :(得分:1)
由于QTableWidgetItem没有可以重载的函数keyEvent(),因此无法实现。
您需要做的是使用自定义编辑器工厂设置一个委托,该工厂生成小部件,其中keyEvent被重载。
答案 2 :(得分:1)
但是仅使用标准物品可以解决它吗? (即只有带有标志Qt :: ItemIsEditable的QTableWidgetItem)
不是真的。在Qt4中,QTableWidget
泄漏了来自单元格编辑器的KeyRelease
个事件,但利用这个将是一个丑陋的黑客攻击。
可能在调用表的grabKeyboard()之后修复损坏的编辑框?
我曾尝试过这样做,然后将事件发布到QTableWidget
,但也遇到了麻烦。
正确的做法是在createEditor
函数中创建自己的委托并安装事件过滤器。你可以这样做:
class FilterDelegate : public QStyledItemDelegate
{
public:
FilterDelegate(QObject *filter, QObject *parent = 0) :
QStyledItemDelegate(parent), filter(filter)
{ }
virtual QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index);
editor->installEventFilter(filter);
return editor;
}
private:
QObject *filter;
};
然后你的MainWindow
构造函数看起来像这样:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
tableWidget->setItemDelegate(new FilterDelegate(this));
tableWidget->installEventFilter(this);
}
您的事件过滤器:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::KeyPress)
{
// do something
}
return QMainWindow::eventFilter(obj, event);
}
答案 3 :(得分:1)
另一个替身:
您可以在QApplication
对象上安装事件过滤器并捕获所有事件。如果你问我这有点矫枉过正,但它适用于一个小应用程序并且只需要很少的代码。
您所要做的就是:
qApp->installEventFilter(this);
和
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::KeyPress)
{
// do something
}
return QMainWindow::eventFilter(obj, event);
}