您的位置:首页 > 编程语言 > Qt开发

关于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 (猜的).

下面是自己测试代码,有瑕疵但是可以实现


.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.html

http://doc.qt.nokia.com/qq/qq11-events.html

/content/839492.html

http://hi.baidu.com/cyclone/blog/item/fe6ab3de0e9f2155ccbf1aea.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: