qt 中 qkeyevent 怎么用?

软件和网站开发以及相关技术探讨
回复
头像
leni
帖子: 1989
注册时间: 2008-09-28 17:24

qt 中 qkeyevent 怎么用?

#1

帖子 leni » 2012-12-06 21:49

举个例子,当我按下PushButton时,LCD显示滑块的数值。当我释放PushButton,我可以改变滑块数值,但是LCD不改变。我想设定上下方向键来改变滑块数值,a键(不用alt键)控制PushButton。如此的话,当我同时按着上键和a键,LCD和滑块的数值就一直增加,放开a键按着上键,滑块增加LCD不变。现在网上查下来,可能要用qkeyevent实现,不过看了也不知道该怎么用。
附件
shortcut.png
shortcut.png (7.75 KiB) 查看 4849 次
latex 是个命令集,不是软件,所以在应用程序里找不到,也不存在启动。使用的话,自己写个 .tex 的文件,用 latex 编译。viewtopic.php?f=35&t=331555 的 4楼 有入门教程PDF下载。
wenwu1225
帖子: 21
注册时间: 2012-06-04 13:15

Re: qt 中 qkeyevent 怎么用?

#2

帖子 wenwu1225 » 2012-12-25 14:01

我觉得你这种情况可以尝试一下在对话框类中添加bool eventFilter(QObject *obj, QEvent *event)函数.
头像
Kandu
帖子: 108
注册时间: 2008-12-24 12:02
联系:

Re: qt 中 qkeyevent 怎么用?

#3

帖子 Kandu » 2012-12-25 20:34

如果出现多个键要按住,释放的情况。光用 event 还不够,因为操作系统*不会*处理这种情况,反映到 Qt, 就是你按住 Key_Up, 重复发出 Key_Up pressed event 然后按住 Key_A, 近重复发出 Key_A event 释放 Key_A, 出现一个 Key_A 释放 event, 此时,虽然你仍然按着 Key_Up 但是并不会出现新 event 了。所以若你要求比较高的话,要写出平滑的程序。这种情况就按照写游戏程序的方式做。也就是自己记录键的按下,释放状态,并用一个定时器定时处理。

因为 QSlider 对 key Up/Down/Left/Right press/release, mouse 都有 accept, 而你要处理 Key_A Key_Up Key_Down。而焦点在 dialog 的其他地方也需要截获这几个 event, 所以对 QApplication installEventFilter 这样就能全局抓住信号了

因为你说只用 Key_A 键控制 pushButton 所以以下代码仅对 Key_A Key_Up Key_Down 进行处理,对 pushButton 的鼠标 event 没有处理。不过同理,若你还需要鼠标控制 pushButton 的话,只要自己写个 filter 对 pushbutton 过滤所有 event,并仅仅对 mouse press/release 进行处理,这样的话, pushbutton 的 up/down 状态不会被其他信号打断。这种情况你,你就可以鼠标按下 pushButton 并按上下键调节 slider 。

代码: 全选

#include <iostream>
#include <QApplication>
#include <QVBoxLayout>
#include <QDialog>
#include <QLCDNumber>
#include <QSlider>
#include <QKeyEvent>
#include <QPushButton>
#include <QTimer>

using namespace std;

bool a_pressed= false;
bool up_pressed= false;
bool down_pressed= false;

class tKeyFilter: public QObject {
    public:
        tKeyFilter(QObject* parent= 0)
            : QObject(parent)
        {
        }
        bool eventFilter(QObject* object, QEvent* event) {
            bool cap= true;
            QKeyEvent* keyEvent;
            if (event->type() == QEvent::KeyPress) {
                keyEvent= static_cast<QKeyEvent*>(event);
                switch (keyEvent->key()) {
                    case Qt::Key_A:
                        a_pressed= true;
                        break;
                    case Qt::Key_Up:
                        up_pressed= true;
                        break;
                    case Qt::Key_Down:
                        down_pressed= true;
                        break;
                    default:
                        cap= false;
                }
            } else if (event->type() == QEvent::KeyRelease) {
                keyEvent= static_cast<QKeyEvent*>(event);
                switch (keyEvent->key()) {
                    case Qt::Key_A:
                        a_pressed= false;
                        break;
                    case Qt::Key_Up:
                        up_pressed= false;
                        break;
                    case Qt::Key_Down:
                        down_pressed= false;
                        break;
                    default:
                        cap= false;
                }
            } else {
                cap= false;
            }
            return cap;
        }
};

class tTimer: public QTimer {
    public:
         tTimer(QPushButton* pb=0, QSlider* sld= 0, QLCDNumber* lcd= 0, QObject* parent= 0)
            :QTimer(parent), pb(pb), sld(sld), lcd(lcd)
         {
         }
    private:
        QPushButton* pb;
        QSlider* sld;
        QLCDNumber* lcd;
        void timerEvent(QTimerEvent*) {
            if (up_pressed) {
                sld->setValue(sld->value()+1);
            }
            if (down_pressed) {
                sld->setValue(sld->value()-1);
            }
            if (a_pressed) {
                pb->setDown(true);
                lcd->display(sld->value());
            } else {
                pb->setDown(false);
            }
        }
};

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    tKeyFilter keyFilter(&app);
    app.installEventFilter(&keyFilter);

    QDialog dlg;
    QVBoxLayout layout(&dlg);

    QLCDNumber lcd;
    QSlider slider(Qt::Horizontal);
    QPushButton button;
    layout.addWidget(&lcd);
    layout.addWidget(&slider);
    layout.addWidget(&button);

    dlg.show();

    tTimer timer(&button, &slider, &lcd, &dlg);
    timer.setInterval(100);
    timer.start();

    return app.exec();
} 
回复