组态软件--控件拖拽

4 篇文章 2 订阅
2 篇文章 0 订阅

组态软件–控件拖拽

个人最近也是在用Qt做组态软件,一开始用QGraphics来做组态软件的UI设计程序,说真的,说真的做出来还有点像样子,但是后续的二次开发存在很大的问题,所以第二次是参考了feiyangqingyun大神的属性设计的思路来做的,可以说做的挺顺利的大概10天就完成了大部分的工作。
首先展示一下做出来的效果
在这里插入图片描述

实现功能

控件的拖动缩放和选中的功能。

相关说明

看过feiyangqingyun的相关博客的同学应该发现了一个问题,自己建一个SelectWidget的QWidget类型的窗口,并配置了一切相关的参数,但是到头来Select绑定了对应的控件也根本不可能使得控件的拖动,但是缩放的功能是真的存在。这里你可能会意识到feiyangqingyun在上传核心代码时将其中的一些使得控件移动的程序删除掉了,需要用户的自行添加。
这里一些比较机智的同学可能会想到feiyangqingyun还有一个movewidget的程序绑定一个控件就可以使得控件移动的程序,添加进去岂不是完美。如果尝试了的话,控件在绑定了SelectWidget和movewidget之后,movewidget根本毫无作用。到这里,代码搬运习惯的人可能就慌了,这明摆着需要自行研读程序并将movewidget中的移动程序移动到Selectwidget中才能实现控件的移动的功能。

两种思路

第一种思路

将控件叠放到SelectWidget之上


bool SelectWidget::eventFilter(QObject *obj, QEvent *event)//此处程序是虚函数,就是空的不要手贱把这个程序删了
{
    QMouseEvent *mouseEvent = (QMouseEvent *)event;

    if(obj==widget&&widget!=nullptr&&move)
    {

        if (mouseEvent->type() == QEvent::MouseButtonPress) {
            //如果限定了只能鼠标左键拖动则判断当前是否是鼠标左键
            if (mouseEvent->button() != Qt::LeftButton) {
                return false;
            }
                widgetpressed=true;
                widgetpressed2=true;
                selected=true;
               // sendSelect(widget);
                sendSelect();
                lastPoint = mouseEvent->globalPos();
                point4=this->pos();
                point5=QPoint(point4.x()+this->width(),point4.y()+this->height());
        }  else if (mouseEvent->type() == QEvent::MouseMove && widgetpressed) {
            //计算坐标偏移值,调用move函数移动过去
                int offsetX = mouseEvent->globalPos().x() - lastPoint.x();
                int offsetY = mouseEvent->globalPos().y() - lastPoint.y();
                this->setGeometry(point4.x()+offsetX,point4.y()+offsetY,point5.x()-point4.x(),point5.y()-point4.y());
        } else if (mouseEvent->type() == QEvent::MouseButtonRelease && widgetpressed) {
            widgetpressed = false;
            sendSelect2();
            lastPoint=mouseEvent->globalPos();
        }
        return QWidget::eventFilter(obj,event);
    }
    else if(obj==this)
    {
        if (mouseEvent->type() == QEvent::MouseButtonPress) {
            //如果限定了只能鼠标左键拖动则判断当前是否是鼠标左键
            if(widgetpressed2==false)
            {
                emit presswidget();
                widgetpressed2=false;
            }
            selected=true;
            if (mouseEvent->button() == Qt::RightButton) {

            }

            //判断控件的区域是否包含了当前鼠标的坐标
            if (this->rect().contains(mouseEvent->pos())) {
                //lastPoint = mouseEvent->pos();
                QPoint point1=mouseEvent->pos();
                point2=this->pos();
                point3=QPoint(point2.x()+this->width(),point2.y()+this->height());

                //这一部分程序注释掉,功能不稳定
              /*  if(point1.x()<20&&point1.y()<20) pressedarea=1;//qDebug()<<"左上"<<endl;
                else if(point1.x()<this->width()*2/3&& point1.x()>this->width()/3&&point1.y()<20) pressedarea=2;// qDebug()<<"中上"<<endl;
                else if(point1.x()>point1.x()-20&&point1.y()<20) pressedarea=3;// qDebug()<<"右上"<<endl;
                else if(point1.x()<20&&point1.y()>this->height()/3&&point1.y()<this->height()*2/3)pressedarea=4;// qDebug()<<"左中"<<endl;
                else if(point1.x()>this->width()-20&&point1.y()>this->height()/3&&point1.y()<this->height()*2/3)pressedarea=5;//qDebug()<<"右中"<<endl;
                else*/ if(point1.x()<20&&point1.y()>this->height()-20)pressedarea=6;// qDebug()<<"左下"<<endl;
                else if(point1.x()<this->width()*2/3&& point1.x()>this->width()/3&&point1.y()>this->height()-20)pressedarea=7;//qDebug()<<"中下"<<endl;
                else if(point1.x()>point1.x()-20&&point1.y()>this->height()-20) pressedarea=8; //qDebug()<<"右下"<<endl;
                else pressedarea=0;
                pressed = true;
            }
        }  else if (mouseEvent->type() == QEvent::MouseMove && pressed) {

            //计算坐标偏移值,调用move函数移动过去
            int offsetX = mouseEvent->pos().x();
            int offsetY = mouseEvent->pos().y();
            int x = point3.x()-point2.x()- offsetX;
            /*if(pressedarea==1)
            {
                this->setGeometry(point2.x()+offsetX,point2.y()+offsetY,point3.x()-point2.x()-offsetX,point3.y()-point2.y()-offsetY);
            }
            else if(pressedarea==2)
                this->setGeometry(point2.x(),point2.y()+offsetY,point3.x()-point2.x(),point3.y()-point2.y()-offsetY);
            else if(pressedarea==3)
                this->setGeometry(point2.x(),point2.y()+offsetY,offsetX,point3.y()-point2.y()-offsetY);
            else if(pressedarea==4)
                this->setGeometry(point2.x()-(x-point3.x()+point2.x()),point2.y(),x,point3.y()-point2.y());
            else if(pressedarea==5)
                this->setGeometry(point2.x(),point2.y(),offsetX,point3.y()-point2.y());
            else*/ if(pressedarea==6)
                this->setGeometry(point2.x()-(x-point3.x()+point2.x()),point2.y(),x,offsetY);
            else if(pressedarea==7)
                this->setGeometry(point2.x(),point2.y(),point3.x()-point2.x(),offsetY);
            else if(pressedarea==8)
                this->setGeometry(point2.x(),point2.y(),offsetX,offsetY);
        } else if (mouseEvent->type() == QEvent::MouseButtonRelease && pressed) {
            pressed = false;
            //lastPoint=mouseEvent->globalPos();
        }

    }

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

这种程序需要将控件的parent设置成SelectWidget,直接将控件叠放到SelectWidget之上,这样控件的坐标一直就是相对于SelectWidget的,只需要移动缩放SelectWidget就可以实现控件的拖动和缩放,可以说极其的方便。但是弊端也是非常的明显的,后期在设置控件属性表时就无法获取控件属性的相应坐标和长宽信息,需要重新设置一个控件属性表来单独的设置控件parent的坐标和长宽信息,可能会影响外观且后期读写xml文件只是需要对xywh进行单独的处理,但是不可否认的是,这种方法设计的界面程序运行非常的流畅,出现意想不到的BUG’的概率也很低。但是这并不是一种主流的方法,毕竟后期会增加一些不必要的代码量,所以第二中才是比较主流的方法。

第二种方法

在同一widget下强行绑定SelectWidget和控件的坐标。


bool SelectWidget::eventFilter(QObject *obj, QEvent *event)//此处程序是虚函数,就是空的不要手贱把这个程序删了
{
    QMouseEvent *mouseEvent = (QMouseEvent *)event;

    if(obj==widget&&widget!=nullptr&&move)
    {
        if (mouseEvent->type() == QEvent::MouseButtonPress) {
            //如果限定了只能鼠标左键拖动则判断当前是否是鼠标左键
            if (mouseEvent->button() != Qt::LeftButton) {
                return false;
            }
                widgetpressed=true;
                widgetpressed2=true;
                selected=true;
               // sendSelect(widget);
                sendSelect();
                lastPoint = mouseEvent->globalPos();
                point4=this->pos();
                point5=QPoint(point4.x()+this->width(),point4.y()+this->height());
        }  else if (mouseEvent->type() == QEvent::MouseMove && widgetpressed) {
            //计算坐标偏移值,调用move函数移动过去
                int offsetX = mouseEvent->globalPos().x() - lastPoint.x();
                int offsetY = mouseEvent->globalPos().y() - lastPoint.y();
                this->setGeometry(point4.x()+offsetX,point4.y()+offsetY,point5.x()-point4.x(),point5.y()-point4.y());
                widget->setGeometry(point4.x()+offsetX+5,point4.y()+offsetY+5,point5.x()-point4.x()-10,point5.y()-point4.y()-10);
        } else if (mouseEvent->type() == QEvent::MouseButtonRelease && widgetpressed) {
            widgetpressed = false;
            sendSelect2();
            lastPoint=mouseEvent->globalPos();
        }
        else  if (event->type() == QEvent::Resize) {
            //设置当前窗体大小为跟随窗体的大小增加部分
            this->setGeometry(widget->x()-5,widget->y()-5,widget->width()+10,widget->height()+10);
        } else if (event->type() == QEvent::Move) {
            //将当前窗体移到偏移位置
            this->setGeometry(widget->x()-5,widget->y()-5,widget->width()+10,widget->height()+10);
        }
        return QWidget::eventFilter(obj,event);
    }
    else if(obj==this)
    {
        if (mouseEvent->type() == QEvent::MouseButtonPress) {
            //如果限定了只能鼠标左键拖动则判断当前是否是鼠标左键
            if(widgetpressed2==false)
            {
                emit presswidget();
                widgetpressed2=false;
            }
            selected=true;
            if (mouseEvent->button() == Qt::RightButton) {

            }

            //判断控件的区域是否包含了当前鼠标的坐标
            if (this->rect().contains(mouseEvent->pos())) {
                //lastPoint = mouseEvent->pos();
                QPoint point1=mouseEvent->pos();
                point2=this->pos();
                point3=QPoint(point2.x()+this->width(),point2.y()+this->height());

                //这一部分程序注释掉,功能不稳定
              /*  if(point1.x()<20&&point1.y()<20) pressedarea=1;//qDebug()<<"左上"<<endl;
                else if(point1.x()<this->width()*2/3&& point1.x()>this->width()/3&&point1.y()<20) pressedarea=2;// qDebug()<<"中上"<<endl;
                else if(point1.x()>point1.x()-20&&point1.y()<20) pressedarea=3;// qDebug()<<"右上"<<endl;
                else if(point1.x()<20&&point1.y()>this->height()/3&&point1.y()<this->height()*2/3)pressedarea=4;// qDebug()<<"左中"<<endl;
                else if(point1.x()>this->width()-20&&point1.y()>this->height()/3&&point1.y()<this->height()*2/3)pressedarea=5;//qDebug()<<"右中"<<endl;
                else*/ if(point1.x()<20&&point1.y()>this->height()-20)pressedarea=6;// qDebug()<<"左下"<<endl;
                else if(point1.x()<this->width()*2/3&& point1.x()>this->width()/3&&point1.y()>this->height()-20)pressedarea=7;//qDebug()<<"中下"<<endl;
                else if(point1.x()>point1.x()-20&&point1.y()>this->height()-20) pressedarea=8; //qDebug()<<"右下"<<endl;
                else pressedarea=0;
                pressed = true;
            }
        }  else if (mouseEvent->type() == QEvent::MouseMove && pressed) {
            selected=true;
            //计算坐标偏移值,调用move函数移动过去
            int offsetX = mouseEvent->pos().x();
            int offsetY = mouseEvent->pos().y();
            int x = point3.x()-point2.x()- offsetX;
            /*if(pressedarea==1)
            {
                this->setGeometry(point2.x()+offsetX,point2.y()+offsetY,point3.x()-point2.x()-offsetX,point3.y()-point2.y()-offsetY);
            }
            else if(pressedarea==2)
                this->setGeometry(point2.x(),point2.y()+offsetY,point3.x()-point2.x(),point3.y()-point2.y()-offsetY);
            else if(pressedarea==3)
                this->setGeometry(point2.x(),point2.y()+offsetY,offsetX,point3.y()-point2.y()-offsetY);
            else if(pressedarea==4)
                this->setGeometry(point2.x()-(x-point3.x()+point2.x()),point2.y(),x,point3.y()-point2.y());
            else if(pressedarea==5)
                this->setGeometry(point2.x(),point2.y(),offsetX,point3.y()-point2.y());
            else*/ if(pressedarea==6)
                this->setGeometry(point2.x()-(x-point3.x()+point2.x()),point2.y(),x,offsetY);
            else if(pressedarea==7)
                this->setGeometry(point2.x(),point2.y(),point3.x()-point2.x(),offsetY);
            else if(pressedarea==8)
                this->setGeometry(point2.x(),point2.y(),offsetX,offsetY);
        } else if (mouseEvent->type() == QEvent::MouseButtonRelease && pressed) {
            pressed = false;
            //lastPoint=mouseEvent->globalPos();
        }

    }

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

毕竟本人比较菜,在设置坐标和大小的程序都使用的是setGeometry,这也可能使得程序在执行的时候可能不太流畅,如果需要可以自行进行优化,改成move和resize两个函数。
本人读研马上要找工作了,这些代码可能对我找工作有点帮助,所以就只能展示一部分。如果以后实在是用不到这些程序,可能会发到github上。

参考的博客

https://qtchina.blog.csdn.net/article/details/100703610

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
回答: 在Python中调用QT界面文件与界面交互的方法有多种。引用\[1\]中的代码示例展示了一种方法,通过导入PyQt5库中的相关模块,创建一个MainWindow类,并在该类中连接QT界面文件,然后通过创建QApplication对象和MainWindow对象来显示界面并运行应用程序。这样可以实现Python代码与QT界面的交互。引用\[2\]中的代码示例展示了使用PyQt4库的方法,通过创建QApplication对象和QPushButton对象,并使用connect函数来连接按钮的点击事件和退出应用程序的操作,从而实现了Python代码与QT界面的交互。引用\[3\]中的代码示例展示了在代码中使用QProcess类来调用Python脚本执行输出操作,并将输出结果显示在label控件中的方法。通过在GUI操作界面上点击按钮来触发脚本的执行,并将结果显示在界面上,实现了Python代码与QT界面的交互。以上是几种常见的Python代码与QT界面交互的方法,具体选择哪种方法取决于你的需求和使用的库版本。 #### 引用[.reference_title] - *1* [python调用QT界面使用方法](https://blog.csdn.net/qq_39025957/article/details/106354885)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [pyqt4 信号与槽方式](https://blog.csdn.net/cw123458945/article/details/8160242)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [设计Qt界面 调用python脚本 输出“Hello Qt”](https://blog.csdn.net/weixin_43604191/article/details/130971911)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值