首页 > 其他 > 详细

QT 实现类似simulink中跨窗口拖动添加组件的方法

时间:2020-09-25 08:05:57      阅读:131      评论:0      收藏:0      [点我收藏+]

想要实现的功能为:在主窗口中点击按钮,弹出一个新的窗口,这个窗口中陈列着可以拖动到主窗口中的组件,拖动这些组件到主窗口,实现在主窗口中生成新组件的功能。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    static bool MouseIn;//用于判断鼠标是否在主窗口中(后期可以更改为是否在特定区域)的布尔变量
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow() override;
protected:
    void enterEvent(QEvent *event) override;//鼠标移动进入主窗口的函数(后期可以改为进入特定区域)
    void leaveEvent(QEvent *event) override;//鼠标离开进入主窗口的函数(后期可以改为离开特定区域)
private slots:
    void on_addBtn_clicked();//按钮,用于弹出组件的陈列窗口
    void newTestButton();//当一切条件满足之后,执行生成组件的槽函数

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "componentwindow.h"
#include "testbutton.h"
#include <QDebug>
#include <QCursor>
#include <QMouseEvent>
#pragma execution_character_set("utf-8")
bool MainWindow::MouseIn = true;//全局静态变量初始化
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::enterEvent(QEvent *event)
{
    Q_UNUSED(event);
    MouseIn = true;
}

void MainWindow::leaveEvent(QEvent *event)
{
    Q_UNUSED(event);
    MouseIn = false;
}

void MainWindow::on_addBtn_clicked()
{
    ComponentWindow *window = ComponentWindow::newComponentWindow();//单例模式,调用静态函数来初始化组件窗口
    window->show();
    connect(window->btn1,SIGNAL(preperNewTestButton()),this,SLOT(newTestButton()),Qt::UniqueConnection);//满足生成按钮的条件之后,会由按钮发出信号,主界面接受信号
}

void MainWindow::newTestButton()
{
    TestButton *btn = new TestButton(this);//生成按钮
    int x=this->mapFromGlobal(QCursor().pos()).x();
    int y=this->mapFromGlobal(QCursor().pos()).y();//获取鼠标在窗口中的坐标而不是全局坐标
    btn->move(x,y);//将鼠标移动至鼠标释放时的位置
    btn->show();
}

ComponentWindow.h

#ifndef COMPONENTWINDOW_H
#define COMPONENTWINDOW_H

#include <QWidget>
#include <QPushButton>
namespace Ui {
class ComponentWindow;
}

class ComponentWindow : public QWidget
{
    Q_OBJECT

public:
    QPushButton *btn1;//声明一个指针,用于保存UI界面上的组件的指针,偷懒写成公有变量
    static ComponentWindow *m_instance;//单例会用到的全局变量
    static ComponentWindow *newComponentWindow();//用于创建组件窗口的函数
    ~ComponentWindow();

private:
    explicit ComponentWindow(QWidget *parent = nullptr);//构造函数声明为私有,就不能用new来创建这个对象,只能通过调用上面的静态函数来执行这个构造函数
    Ui::ComponentWindow *ui;
};

#endif // COMPONENTWINDOW_H

component.cpp

#include "componentwindow.h"
#include "ui_componentwindow.h"
#include "mainwindow.h"

#pragma execution_character_set("utf-8")
ComponentWindow * ComponentWindow::m_instance=nullptr;//静态全局变量初始化
ComponentWindow::ComponentWindow(QWidget *parent) :QWidget(parent),ui(new Ui::ComponentWindow)
{
    ui->setupUi(this);
    btn1 = ui->btn_1;//将UI界面上的组件指针赋值给
}

ComponentWindow *ComponentWindow::newComponentWindow()
{
    if(m_instance==nullptr)
    {
        m_instance = new ComponentWindow();
    }
    return m_instance;
    //最最简单的单例写法
}

ComponentWindow::~ComponentWindow()
{
    delete ui;
}

由于组件以后还会有一些特殊的功能,所以需要自己去继承,并完成新的功能编辑,这里继承了QPushButton。

#ifndef TESTBUTTON_H
#define TESTBUTTON_H
#include <QPushButton>
#include <QMouseEvent>

class TestButton : public QPushButton
{
    Q_OBJECT
public:
    explicit TestButton(QWidget *parent=0);
protected:
    void mousePressEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    //三个鼠标事件
signals:
    void preperNewTestButton();
private slots:

private:
    QPoint pressPoint;
};

#endif // TESTBUTTON_H

testButton.cpp

#include "testbutton.h"
#include "mainwindow.h"
#include <QDebug>
#pragma execution_character_set("utf-8")

TestButton::TestButton(QWidget *parent):QPushButton (parent)
{

}

void TestButton::mousePressEvent(QMouseEvent *event)
{
    /*
    if(event->button() == Qt::LeftButton)
    {
        this->raise(); //将此按钮移动到顶层显示
        this->pressPoint = event->pos();
    }
    */
}

void TestButton::mouseReleaseEvent(QMouseEvent *event)
{
    if(MainWindow::MouseIn)//获取鼠标的位置状态的布尔函数,由于MouseIn是静态变量,所以需要用名称空间符号::来访问
    {
        emit preperNewTestButton();//当鼠标在指定区域时,发出信号准备生成按钮
    }
    else
    {
        return;//否则什么都不干,当然这个功能后面会完善
    }
}

void TestButton::mouseMoveEvent(QMouseEvent *event)
{
    /*
    if(event->buttons() == Qt::LeftButton)
    {
        this->move(this->mapToParent(event->pos() - this->pressPoint));
    }
    */
}

基本上拖动的功能是有了,但是后面还需要再完善一下。

QT 实现类似simulink中跨窗口拖动添加组件的方法

原文:https://www.cnblogs.com/leocc325/p/13727532.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!