想要实现的功能为:在主窗口中点击按钮,弹出一个新的窗口,这个窗口中陈列着可以拖动到主窗口中的组件,拖动这些组件到主窗口,实现在主窗口中生成新组件的功能。
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)); } */ }
基本上拖动的功能是有了,但是后面还需要再完善一下。
原文:https://www.cnblogs.com/leocc325/p/13727532.html