qt编写触摸事件的关键

这篇博客介绍了如何在Qt应用程序中启用触摸事件,包括按钮的触摸点击、控件的触摸拖动以及触摸长按弹出对话框。通过setAttribute(Qt::WA_AcceptTouchEvents)设置控件支持多点触控,然后重写相关事件处理函数,实现了触摸屏上的各种交互操作。示例代码详细展示了按钮、自定义控件及长按事件的处理方式。
摘要由CSDN通过智能技术生成

提要

无论你的电脑是支持触摸屏,还是你通过usb外部连接触摸屏,都能验证你的触摸程序功能。下面说说程序中使用触摸按钮等。

示例

  1. 按钮可以实现触摸功能;
  2. 自动义控件可以实现触摸按下拖动;
  3. 触摸长按出现对话框(也可以是其它控件)。

按钮可以实现触摸功能

只需要在该按钮所在的对话框的构造函数中添加下面一句:

setAttribute(Qt::WA_AcceptTouchEvents);//支持多点触控

使用的是控件自身的事件,比如按钮的clicked槽函数,添加上面的支持触控后,触摸点击按钮后就会执行槽函数相应的操作。

自动义控件可以实现触摸按下拖动

同样需要在其构造函数中添加设置支持多点触控的属性;

setAttribute(Qt::WA_AcceptTouchEvents);//支持多点触控

然后在需要拖动的控件的类中重写鼠标的按下,移动,释放事件。

//相关变量定义
 QPoint      m_beginPos;//鼠标点击的起始位置
 QPoint      m_leftTopPos;//窗口左上角的位置
 bool        m_isTitle;//点击的点是否在标题栏上
    
void configBtnNameDialog::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        //在标题栏中点击
        if(ui->widgetTitle->rect().contains(event->pos()))//注意此时使用pos()而不能使用globalPos()
        {
            m_beginPos = event->globalPos();//刚开始按下点的坐标
            m_leftTopPos = pos();//窗口左上角坐标
            m_isTitle = true;//是窗口标题栏
        }
    }
    QDialog::mousePressEvent(event);
}

void configBtnNameDialog::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() == Qt::LeftButton && m_isTitle)//如果按下的是左键,且位置在标题栏上
    {
        QPoint endPos = event->globalPos();//结束点坐标
        QPoint offPos = endPos - m_beginPos;//结束点与开始点坐标差
        QPoint pos = m_leftTopPos + offPos;//左上角坐标加偏移量
        move(pos);//移动到该点
    }
    QDialog::mouseMoveEvent(event);//不可忘掉
}

void configBtnNameDialog::mouseReleaseEvent(QMouseEvent *event)
{
    m_isTitle = false;
    QDialog::mouseReleaseEvent(event);
}

其中ui->widgetTitle为自定义的标题栏。实际上这种事件的编写,还是之前没有触摸屏时一样的事件,只是添加了支持多点触控的属性,便可以手动触摸拖动窗口标题栏。

触摸长按出现对话框(也可以是其它控件)

在按钮上长按几秒出现对话框,由于是自定义的按钮,所以需要在按钮中重写event事件,在event事件中实现长按出对话框。
同样需要在其自定义的按钮的构造函数中添加设置支持多点触控的属性;

setAttribute(Qt::WA_AcceptTouchEvents);//支持多点触控

下面是event函数的定义

//变量定义
bool        m_isLongPress;//是否触屏长按
int         m_second = 0;//当前的秒数
QTime       m_begintime;//开始长按的时间

bool myButton::event(QEvent *event)
{
    switch(event->type())
    {
        case QEvent::TouchBegin:
        {
            QTouchEvent* touch = static_cast<QTouchEvent*>(event);
            QList<QTouchEvent::TouchPoint> touchPoints = touch->touchPoints();
            outPut<<"myButton::event->TouchBegin点的个数为:"<<touchPoints.count();
            if(touchPoints.count() == 1)
            {
                m_begintime = QTime::currentTime();
                m_second = m_begintime.hour()*3600+m_begintime.minute()*60+m_begintime.second();
                outPut<<"开始时间:"<<m_begintime<<"当前秒数:"<<m_second;
                m_isLongPress = true;
            }
            event->accept();
        }
        case QEvent::TouchUpdate:
        {
            QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
            QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
            outPut<<"myButton::event->TouchUpdate点的个数为:"<<touchPoints.count();
            if (touchPoints.count() == 1)
            {
                outPut<<"touchPoints.count() == 1";
                if(m_isLongPress)
                {
                    outPut<<"正在被按下";
                    QTime current_time =QTime::currentTime();
                    int secondEnd = current_time.hour()*3600+current_time.minute()*60+current_time.second();
                    outPut<<"时间:"<<secondEnd;
                    if(secondEnd - m_second >= 1)
                    {
                        //长按2秒显示设置名称的对话框
                        showEditNameDlg();
                        outPut<<"长按显示对话框"<<"起始时间:"<<m_begintime<<"终止时间:"<<current_time;
                    }
                }
            }
            return true;
        }
        case QEvent::TouchEnd:
        {
            m_isLongPress = false;
            event->accept();
            outPut<<"释放";
            return true;
        }
        default:
            break;
    }
    return QPushButton::event(event);
}

以上是触摸长按出对话框,中间长按等待的时间可能会不一样,有时很短的时间可以出对话框,有时很长一段时间才出对话框,究其原因是进入TouchUpdate的时间不一样,如下面这样,可以很快出对话框,因为检测到了长按时间超过1秒。

2021-03-25 13:59:41 Debug:myButton::event [ 160 ] myButton::event->TouchBegin点的个数为: 1
2021-03-25 13:59:41 Debug:myButton::event [ 165 ] 开始时间: QTime(“13:59:41.356”) 当前秒数: 50381
2021-03-25 13:59:41 Debug:myButton::event [ 174 ] myButton::event->TouchUpdate点的个数为: 1
2021-03-25 13:59:41 Debug:myButton::event [ 177 ] touchPoints.count() == 1
2021-03-25 13:59:41 Debug:myButton::event [ 180 ] 正在被按下
2021-03-25 13:59:41 Debug:myButton::event [ 183 ] 时间: 50381
2021-03-25 13:59:55 Debug:myButton::event [ 174 ] myButton::event->TouchUpdate点的个数为: 1
2021-03-25 13:59:55 Debug:myButton::event [ 177 ] touchPoints.count() == 1
2021-03-25 13:59:55 Debug:myButton::event [ 180 ] 正在被按下
2021-03-25 13:59:55 Debug:myButton::event [ 183 ] 时间: 50395
2021-03-25 13:59:55 Debug:myButton::event [ 188 ] 长按显示对话框 起始时间: QTime(“13:59:41.356”) 终止时间: QTime(“13:59:55.029”)
2021-03-25 13:59:55 Debug:myButton::event [ 198 ] 释放

以上就可以通过触摸屏长按很快显示对话框,但是下面却不是,中间需要一直等待程序再次进入TouchUpdate。甚至于一直长按触摸屏,没有释放,程序也会检测到已经释放,输出释放信息。

2021-03-25 13:56:46 Debug:myButton::event [ 165 ] 开始时间: QTime(“13:56:46.032”) 当前秒数: 50206
2021-03-25 13:56:46 Debug:myButton::event [ 174 ] myButton::event->TouchUpdate点的个数为: 1
2021-03-25 13:56:46 Debug:myButton::event [ 177 ] touchPoints.count() == 1
2021-03-25 13:56:46 Debug:myButton::event [ 180 ] 正在被按下
2021-03-25 13:56:46 Debug:myButton::event [ 183 ] 时间: 50206
2021-03-25 13:56:47 Debug:myButton::event [ 198 ] 释放
2021-03-25 13:51:34 Debug:myButton::event [ 160 ] myButton::event->TouchBegin点的个数为: 1
2021-03-25 13:51:34 Debug:myButton::event [ 165 ] 开始时间: QTime(“13:51:34.172”) 当前秒数: 49894
2021-03-25 13:51:34 Debug:myButton::event [ 175 ] myButton::event->TouchUpdate点的个数为: 1
2021-03-25 13:51:34 Debug:myButton::event [ 178 ] touchPoints.count() == 1
2021-03-25 13:51:34 Debug:myButton::event [ 181 ] 正在被按下
2021-03-25 13:51:34 Debug:myButton::event [ 186 ] 时间: 49894
2021-03-25 13:51:37 Debug:myButton::event [ 203 ] 释放

但是功能上应该是正确的,可以实现长按触摸屏出现对话框。

总结

1.添加设置触摸属性,setAttribute(Qt::WA_AcceptTouchEvents);;
常规的按键之类的可以直接实现。
2.复杂一点在event事件中实现相关功能。
注意:以上可能只适用于窗口,小控件,至于场景视图这些不一定完全适用,还需做一些改动。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肩上风骋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值