关于qtablewidget中单元格按键改写
2012-08-11 14:10
609 查看
主要功能是在qtbalewidget的单元格编辑状态下,实现按键盘KEY_A改写KEY_B,MD,艹..首先骂两句..这个问题折腾我接近一个星期时间,一方面自己是新手,对控件以及QT事件信息处理机构不熟悉,导致无论是event 还是keypressevent 常规做法都不能拦截原本KEY的输出,后来在前辈的指点下用installEventFilter监听整个app,嘿嘿,这下所以得信号都给拦截了,所以就可以改写了,qtablewidget的单元格是比较特殊的,第一次点击的时候是触发tablewidget(可以将整个tablewidget设置成不可编辑,这样可以不输出原本KEY,但是这种做法太烂了),第二次点击的时候是继承的Line
Edit (猜的).
下面是自己测试代码,有瑕疵但是可以实现
Qt中的事件大致可分为3类:
本文中,先简单看一下后两种,然后重点看看第一种。
比如,发送按键"X"的事件到 mainWin 窗口。
如果没有过滤器的话,这其实就是直接调用 mainWin 的 keyPressEvent()函数。
(图片来源:http://www.slideshare.net/mariusbu/qt-widgets-in-depth,下同)
这个东西不涉及事件队列、事件循环等等东西。但是事件过滤在这个过程中正常起作用。而且除过滤器外,下面三个函数在派生类中都可以被覆盖(以处理这个事件):
QApplication::notify()
QWidget::event()
QWidget::keyPressEvent()
比如,同样是发送按键"X"的事件到 mainWin 窗口,我们可以使用postEvent()。
这会将该事件放入Qt自己的事件队列中,事件循环QEventLoop空闲时会判断该队列是否为空。最终使用 sendEvent() 依次派发事件队列中的这些事件。
也可以手动使用
QCoreApplication::sendPostedEvents()
清空当前线程事件队列(即派发队列中的事件)
注意:每一个线程有一个事件队列。
系统底层事件是通过 QAbstractEventDispatcher 整合进Qt的事件循环的。
Event dispatcher接受窗口系统以及其他源中的事件。它对事件的传递提供了一种精细控制的能力。
QAbstractEventDispatcher
QEventDispatcherUNIX
QEventDispatcherX11
QEventDispatcherQWS
QEventDispatcherQPA
QEventDispatcherGlib
QGuiEventDispatcherGlib
QWSEventDispatcherGlib
QEventDispatcherWin32
QGuiEventDispatcherWin32
QEventDispatcherMac
...
这堆东西还挺多,不过下面三个属于QtCore模块
我们能看的到的就是,它们提供
Timer
SockerNotifer
的注册、反注册功能。并将系统底层对应事件转换成Qt事件。
其他的属于QtGui模块。就是和窗口系统(重绘、移动等等事件)以及键鼠事件有关了。
http://doc.qt.nokia.com/4.7/eventsandfilters.html
http://doc.qt.nokia.com/qq/qq11-events.html
/content/839492.html
http://hi.baidu.com/cyclone/blog/item/fe6ab3de0e9f2155ccbf1aea.html
Edit (猜的).
下面是自己测试代码,有瑕疵但是可以实现
.h MainWindow(QObject *target); bool eventFilter(QObject *target,QEvent *event); .main.cpp 传入APP int main(int argc, char *argv[]){ QApplication app(argc, argv); MainWindow mainWin(&app); mainWin.show(); return app.exec();}.cpp 安装事件过滤器 MainWindow::MainWindow(QObject *target) { target->installEventFilter(this); } //改写 bool MainWindow::eventFilter(QObject *target,QEvent *event) { //if(target == spreadsheet) { if(event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if(keyEvent->key() == Qt::Key_A) { QKeyEvent event(QEvent::KeyPress,Qt::Key_B,Qt::NoModifier,"B", 0); QApplication::sendEvent(target,&event); return true; } } } return QWidget::eventFilter(target, event); }
参考资料:http://www.oschina.net/question/234345_52612
Qt中的事件大致可分为3类:
Spontaneous events | 从系统得到的消息:鼠标按键、键盘按键、定时器事件等。转化为QEvent后被Qt事件系统依次处理 |
Posted events | 由Qt或应用程序直接生成,放入Qt消息队列 QCoreApplication::postEvent() |
Sent events | 由Qt或应用程序产生,不放入队列直接被派发和处理 QCoreApplication::sendEvent() |
Sent events
比如,发送按键"X"的事件到 mainWin 窗口。QKeyEvent event(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X", 0 ); QApplication::sendEvent(mainWin, &event);
如果没有过滤器的话,这其实就是直接调用 mainWin 的 keyPressEvent()函数。
(图片来源:http://www.slideshare.net/mariusbu/qt-widgets-in-depth,下同)
这个东西不涉及事件队列、事件循环等等东西。但是事件过滤在这个过程中正常起作用。而且除过滤器外,下面三个函数在派生类中都可以被覆盖(以处理这个事件):
QApplication::notify()
QWidget::event()
QWidget::keyPressEvent()
Posted events
比如,同样是发送按键"X"的事件到 mainWin 窗口,我们可以使用postEvent()。QApplication::postEvent(mainWin, new QKeyEvent(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X", 0 ));
这会将该事件放入Qt自己的事件队列中,事件循环QEventLoop空闲时会判断该队列是否为空。最终使用 sendEvent() 依次派发事件队列中的这些事件。
也可以手动使用
QCoreApplication::sendPostedEvents()
清空当前线程事件队列(即派发队列中的事件)
注意:每一个线程有一个事件队列。
Spontaneous events
系统底层事件是通过 QAbstractEventDispatcher 整合进Qt的事件循环的。Event dispatcher接受窗口系统以及其他源中的事件。它对事件的传递提供了一种精细控制的能力。
QAbstractEventDispatcher
QEventDispatcherUNIX
QEventDispatcherX11
QEventDispatcherQWS
QEventDispatcherQPA
QEventDispatcherGlib
QGuiEventDispatcherGlib
QWSEventDispatcherGlib
QEventDispatcherWin32
QGuiEventDispatcherWin32
QEventDispatcherMac
...
这堆东西还挺多,不过下面三个属于QtCore模块
QEventDispatcherGlib | 使用glib事件循环,有助于和Gtk的集成 |
QEventDispatcherUNIX | 默认的glib不可用时,就用这个喽 |
QEventDispatcherWin32 | Qt 创建一个带回调函数的隐藏窗口来处理事件。 |
Timer
SockerNotifer
的注册、反注册功能。并将系统底层对应事件转换成Qt事件。
其他的属于QtGui模块。就是和窗口系统(重绘、移动等等事件)以及键鼠事件有关了。
参考
http://doc.qt.nokia.com/4.7/eventsandfilters.htmlhttp://doc.qt.nokia.com/qq/qq11-events.html
/content/839492.html
http://hi.baidu.com/cyclone/blog/item/fe6ab3de0e9f2155ccbf1aea.html
相关文章推荐
- 关于qtablewidgetitem-setitemprototype的理解
- QTableWidget 用法总结(只能使用标准的数据模型,并且其单元格数据是QTableWidgetItem的对象)
- 关于QTableWidget的item所占内存的释放问题
- 关于QTableWidgetItem占用内存的释放
- 关于QTableWidget插入数据库数据很慢的原因
- 关于QTableWidget里的滚动条问题
- 关于QTableWidget的item所占内存的释放问题
- 关于QTreeWidget显示类似QTableWidget网格的实现
- qtablewidget 的单元格内放图片
- 关于QTableWidget 表头设置无效的原因
- 关于QTableWidget的item所占内存的释放问题
- QTableWidget 空单元格,忽略点击事件
- 关于QTableWidget使用setCellWidget嵌入控件错位的问题
- qt Qtablewidget某些单元格的控件不显示
- 关于QTableWidgetItem::setItemPrototype的理解
- 关于QTableWidget的selectRange
- QTableWidget单元格控件居中对齐
- 关于QTableWidget的item所占内存的释放问题
- QT QTableWidget中实现整行选中和禁止编辑单元格
- 关于QTableView和QTableWidget设置代理的相关问题