Qt自定义控件1-录像时间选择

一、作品说明

        在视频监控系统中,往往会涉及到视频录像或者特定事件录像的情况,由此需要选取合适的时间范围,要求能够灵活、多段选取,并且时间精确到分钟,可以实现直观显示、删除和保存时间等多种功能。纯Qt编写,源码可使用QtCreator直接编译使用,也可以在此基础上做二次开发,持续更新完善升级维护,欢迎各位交流讨论。

        备注:开发版本为Qt5.1.0-msvc2012-x64-opengl

二、控件功能

        1.纯Qt编写,支持跨平台编译

        2.支持鼠标拖动选取时间

        3.支持时间标签移动

        4.支持显示标签时间范围

        5.支持改变标签颜色

        6.支持获取所有标签时间值

        7.支持标签删除

        8.支持多种标签颜色

        9.支持标签伸缩改变时间范围

        10.支持QtCreatror编译成插件,在QtDesigner中使用

三、作品展示

时间录像控件

四、核心代码

/*
**功能:事件过滤器
**参数:object,转换为时间标签对象
**参数:event,事件
**返回值:布尔值
*/
bool QtzEventTime::eventFilter(QObject *object, QEvent *event)
{
    QtzLabel* timeLabel=(QtzLabel*)object;
    QMouseEvent *mouseEvent=static_cast<QMouseEvent*>(event);

    if(mouseEvent->type() == QEvent::MouseButtonPress)
    {
        /*鼠标按下,隐藏时间提示*/
        d->timeTip->hide();
        d->pressTip->hide();

        /*获取时间段内容*/
        QString startContent=getHourAndMinute(timeLabel->x());
        QString endContent=getHourAndMinute(timeLabel->x()+timeLabel->rect().width());
        QString content=QString("%1:%2").arg(startContent).arg(endContent);
        Q_EMIT sendContent(content);

        /*计算标签提示的新坐标*/
        int x=timeLabel->x()+(timeLabel->rect().width())/2-d->pressTip->size().width()/2;
        int y=timeLabel->y()-d->pressTip->size().height();
        d->pressTip->move(mapToGlobal(QPoint(x,y)));
        d->pressTip->show();

        QString propertyName=timeLabel->objectName();

        if (propertyName == QStringLiteral("定时"))
        {
            d->typeValue=propertyName;
        }
        else if (propertyName == QStringLiteral("报警"))
        {
            d->typeValue=propertyName;
        }
        else if (propertyName == QStringLiteral("动测或报警"))
        {
            d->typeValue=propertyName;
        }
        else if (propertyName == QStringLiteral("事件"))
        {
            d->typeValue=propertyName;
        }

        Q_EMIT sendType(d->typeValue);

        Q_EMIT hideAll();

        d->delLabel=timeLabel;

        if(mouseEvent->button()==Qt::LeftButton)
        {
            d->lastPos = mouseEvent->pos();

            if(timeLabel->rect().contains(mouseEvent->pos()))
            {
                d->isPressed = true;

                /*鼠标按下,同时检测选中标签周围的标签索引,鼠标移动过程中不检测*/
                findNearestLabel(timeLabel,QPoint());

                if(d->frontLabel!=timeLabel)
                {
                    if(d->frontLabel!=nullptr)
                    {
                        /*将前一个时间标签的锚点区域擦掉*/
                        connect(this,SIGNAL(drawAnchor(bool)),d->frontLabel,SLOT(drawAnchor(bool)));
                        Q_EMIT drawAnchor(false);
                        /*绘制完释放信号连接*/
                        disconnect(this,SIGNAL(drawAnchor(bool)),d->frontLabel,SLOT(drawAnchor(bool)));
                    }

                    /*记录当前时间区域标签*/
                    d->frontLabel = timeLabel;
                    /*鼠标按下开始绘制当前时间区域锚点区域*/
                    connect(this,SIGNAL(drawAnchor(bool)),timeLabel,SLOT(drawAnchor(bool)));
                    /*是否绘制锚点区域*/
                    Q_EMIT drawAnchor(true);
                    /*绘制完释放信号连接*/
                    disconnect(this,SIGNAL(drawAnchor(bool)),timeLabel,SLOT(drawAnchor(bool)));

                    /*恢复初值*/
                    d->frontLabel = nullptr;
                }
            }
        }
    }
    else if(mouseEvent->type() == QEvent::MouseMove && d->isPressed)
    {
        /*设置移动最小坐标范围*/
        int minX = linearToPaint(0);
        /*设置移动最大坐标范围*/
        int maxX = linearToPaint(24);

        /*计算坐标偏移值*/
        int offX = mouseEvent->pos().x() - d->lastPos.x();
        /*生成新的横纵坐标*/
        int x = timeLabel->x()+offX;
        int y = timeLabel->y();

        /*碰撞检测,通过offX确定移动的方向,左或者右*/
        bool result=collisionDetection(x,timeLabel,offX);

        /*使用move函数移动标签区域*/
        if(x>=minX && x<=maxX-timeLabel->rect().width() && result)
        {
            if(!d->isStretchMove)
                timeLabel->move(x,y);
        }

        d->pressTip->hide();

        /*计算标签提示的新坐标*/
        int sx=timeLabel->x()-d->startTip->size().width()/2;
        int sy=timeLabel->y()-d->startTip->size().height();
        d->startTip->move(mapToGlobal(QPoint(sx,sy)));

        /*获取时间段内容*/
        QString startContent=getHourAndMinute(timeLabel->x());
        d->startTip->setContent(startContent);
        /*鼠标进入标签范围,显示时间提示*/
        d->startTip->show();

        /*计算标签提示的新坐标*/
        int ex=timeLabel->x()+timeLabel->rect().width()-d->endTip->size().width()/2;
        int ey=timeLabel->y()-d->endTip->size().height();
        d->endTip->move(mapToGlobal(QPoint(ex,ey)));

        /*获取时间段内容*/
        QString endContent=getHourAndMinute(timeLabel->x()+timeLabel->rect().width());
        d->endTip->setContent(endContent);
        /*鼠标进入标签范围,显示时间提示*/
        d->endTip->show();
    }
    else if (mouseEvent->type() == QEvent::MouseButtonRelease && d->isPressed)
    {
       d->isPressed = false;

       /*鼠标释放,同时清理连表索引内容*/
       if(!d->labelIndex.isEmpty())
           d->labelIndex.clear();

       /*鼠标释放,隐藏时间提示*/
       d->startTip->hide();
       d->endTip->hide();
    }
    else if (mouseEvent->type() == QEvent::Enter)
    {
        /*计算标签提示的新坐标*/
        int x=timeLabel->x()+(timeLabel->rect().width())/2-d->timeTip->size().width()/2;
        int y=timeLabel->y()-d->timeTip->size().height();
        d->timeTip->move(mapToGlobal(QPoint(x,y)));

        /*获取时间段内容*/
        QString startContent=getHourAndMinute(timeLabel->x());
        QString endContent=getHourAndMinute(timeLabel->x()+timeLabel->rect().width());
        QString content=QString("%1-%2").arg(startContent).arg(endContent);
		QString type=timeLabel->objectName();
        d->timeTip->setContent(QString("%1\n%2").arg(type).arg(content));
        /*鼠标进入标签范围,显示时间提示*/
        d->timeTip->show();
    }
    else if(mouseEvent->type() == QEvent::Leave)
    {
        /*鼠标离开标签范围,隐藏时间提示*/
        d->timeTip->hide();
    }

    return QWidget::eventFilter(object, event);
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
旋转仪表盘是一种常见的显示控件,可以用来展示一些数据,如速度、油量、温度等,下面我将介绍如何使用Qt编写一个旋转仪表盘控件。 首先,我们需要在Qt中创建一个新的自定义控件类。可以通过Qt Creator中的“添加新文件”功能来创建一个QWidget派生类。在这个类中,我们需要实现paintEvent()函数来绘制仪表盘。 在paintEvent()函数中,我们可以使用QPainter来绘制仪表盘的各个部分,包括刻度线、指针、文字等。具体实现可以参考以下代码: ```C++ void RotatingDial::paintEvent(QPaintEvent *event) { // 设置背景色 QPalette pal(palette()); pal.setColor(QPalette::Background, Qt::white); setAutoFillBackground(true); setPalette(pal); // 绘制刻度线 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.translate(width() / 2, height() / 2); painter.setPen(QPen(Qt::black, 2)); for (int i = 0; i < 60; i++) { painter.drawLine(0, -100, 0, -90); painter.rotate(6); } // 绘制指针 painter.save(); painter.rotate(m_angle); painter.setBrush(Qt::red); painter.setPen(Qt::NoPen); painter.drawConvexPolygon(m_pointer, 3); painter.restore(); // 绘制文字 QFont font("Arial", 12, QFont::Bold); painter.setFont(font); painter.drawText(-30, 50, "Speed"); } ``` 在上面的代码中,我们首先设置了控件的背景色为白色。然后使用QPainter绘制了60条刻度线,并旋转6度。接着,我们绘制了一个红色的指针,并根据m_angle属性来旋转指针的角度。最后,我们使用QPainter绘制了文字“Speed”。 在我们的自定义控件中,我们需要一个属性来控制指针的角度。我们可以使用Q_PROPERTY宏来定义这个属性,例如: ```C++ class RotatingDial : public QWidget { Q_OBJECT Q_PROPERTY(int angle READ angle WRITE setAngle) public: RotatingDial(QWidget *parent = nullptr); int angle() const; void setAngle(int angle); private: int m_angle; QPolygon m_pointer; }; ``` 在上面的代码中,我们使用Q_PROPERTY宏定义了angle属性,并提供了getter和setter函数。我们还定义了一个私有变量m_angle来存储当前的角度,以及一个QPolygon对象m_pointer来存储指针的形状。 在setAngle()函数中,我们设置m_angle属性,并根据新的角度计算指针的位置: ```C++ void RotatingDial::setAngle(int angle) { if (angle != m_angle) { m_angle = angle; m_pointer.setPoint(0, QPoint(0, -90)); m_pointer.setPoint(1, QPoint(5, 0)); m_pointer.setPoint(2, QPoint(-5, 0)); m_pointer.translate(0, 100); update(); } } ``` 在上面的代码中,我们首先判断新的角度是否与当前的角度相同。如果不同,我们就更新m_angle属性,并重新计算指针的位置。最后,我们调用update()函数来触发paintEvent()函数的调用,从而完成控件的重绘。 最后,我们可以在MainWindow类中使用我们的自定义控件,例如: ```C++ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { RotatingDial *dial = new RotatingDial(this); dial->setAngle(30); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(dial); setCentralWidget(new QWidget); centralWidget()->setLayout(layout); } ``` 在上面的代码中,我们创建了一个RotatingDial对象,并设置了初始角度为30度。然后,将其添加到QHBoxLayout布局中,并设置为主窗口的中央控件。 至此,我们已经完成了一个简单的旋转仪表盘的自定义控件。你可以根据需要对其进行扩展和优化,使其更加适合你的应用场景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值