初学C++,想实现小方块的点击和移动,直接给小方块的父元素 widget_7 绑定了事件监听,虽然实现了,却不理想。
#include <QMouseEvent>
#include "dragwin.h"
QPoint MediaServer::m_qMousePoint;
bool MediaServer::m_bIsMousePressed = false;
DragWin* MediaServer::curWidget;
MediaServer::MediaServer(QWidget *parent) :
QWidget(parent),
ui(new Ui::MediaServer)
{
ui->setupUi(this);
ui->widget_7->installEventFilter(this); // 操作区
}
bool MediaServer::eventFilter(QObject *watched, QEvent *event) {
QMouseEvent* pEvent = static_cast<QMouseEvent *>(event); //将事件转换成鼠标事件,进行鼠标事件过滤
switch (pEvent->type())
{
case QEvent::MouseButtonPress: //单击
if(pEvent->button() == Qt::LeftButton)
{
m_bIsMousePressed = true;
curWidget = qobject_cast<DragWin*>(watched);
m_qMousePoint = pEvent->globalPos() - curWidget->pos(); //如果左键按下则记录当前鼠标在widget中位置
qDebug() << "鼠标按下 pEvent->globalPos() ==== " << pEvent->globalPos();
qDebug() << "鼠标按下 curWidget->pos() ==== " << curWidget->pos();
}
return true;
case QEvent::MouseButtonRelease:
if(pEvent->button() == Qt::LeftButton)
{
QList<DragWin*> labelList = ui->widget_7->findChildren<DragWin*>();
for(int i = 0; i < labelList.size(); i++)
{
DragWin* label = labelList.at(i);
label->setStyleSheet("background:#fff;border:1px solid #ccc;margin:0;");
}
curWidget = qobject_cast<DragWin*>(watched);
curWidget->setStyleSheet("background:#fff;border:10px solid red;margin:0;");
ui->winX->setText(QString::number(curWidget->pos().x()));
ui->winY->setText(QString::number(curWidget->pos().y()));
ui->winW->setText(QString::number(curWidget->rect().width()));
ui->winH->setText(QString::number(curWidget->rect().height()));
m_bIsMousePressed = false;
qDebug() << "鼠标释放 pEvent->globalPos() ==== " << pEvent->globalPos();
}
return true;
case QEvent::MouseMove:
if(m_bIsMousePressed && (pEvent->buttons() == Qt::LeftButton))
{
qDebug() << "小窗口拖拽 event->type()==== " << event->type();
curWidget = qobject_cast<DragWin*>(watched);
int iL= pEvent->globalPos().x() - m_qMousePoint.x();
int iT= pEvent->globalPos().y() - m_qMousePoint.y();
iL <= 0 && (iL = 0);
iT <= 0 && (iT = 0);
curWidget->move(iL, iT);
ui->winX->setText(QString::number(iL));
ui->winY->setText(QString::number(iT));
qDebug() << "鼠标拖拽 pEvent->globalPos() ==== " << pEvent->globalPos();
qDebug() << "鼠标拖拽 m_qMousePoint ==== " << m_qMousePoint;
return true;
}
default:
break;
}
return QWidget::eventFilter(watched, event);
}
#ifndef MEDIASERVER_H
#define MEDIASERVER_H
#include <QWidget>
#include "dragwin.h"
using namespace neb;
QT_BEGIN_NAMESPACE
namespace Ui { class MediaServer; }
QT_END_NAMESPACE
class MediaServer : public QWidget
{
Q_OBJECT
public:
explicit MediaServer(QWidget *parent = nullptr);
~MediaServer();
protected:
bool eventFilter(QObject *watched, QEvent *event) ;
public:
static DragWin* curWidget;
static QPoint m_qMousePoint; //记录当前位置
static bool m_bIsMousePressed; //记录鼠标松放
private:
Ui::MediaServer *ui;
DragWin* newWidget = nullptr;
QVector<DragWin*> winList;
};
#endif // MEDIASERVER_H
DragWin是方块类,后来把事件写到类里实现。可以看下大概思路
#include "dragwin.h"
#include "mediaserver.h"
#include <QDebug>
#include <QMouseEvent>
DragWin::DragWin(QWidget *parent) : PainterGragh(parent)
{
this->setCursor(QCursor(Qt::DragLinkCursor));
}
int DragWin::parseJSON(CJsonObject je) {
je.Get("winId",winId);
je.Get("winx", winX);
je.Get("winy", winY);
je.Get("winw", winW);
je.Get("winh", winH);
je.Get("winz", winZ);
return 0;
}
void DragWin::mousePressEvent(QMouseEvent *event)//QMouseEvent *event
{
// QMouseEvent* pEvent = static_cast<QMouseEvent *>(event);
if(event->button()==Qt::LeftButton)
{
m_bIsMouseMove = false;
MediaServer::m_bIsMousePressed = true;
// m->curWidget = qobject_cast<QWidget*>(watched);
MediaServer::curWidget = this;
MediaServer::m_qMousePoint = event->globalPos() - MediaServer::curWidget->pos(); //如果左键按下则记录当前鼠标在widget中位置
}
else if(event->button()==Qt::RightButton)
{
qDebug()<<"RightButton clicked!!!!!!!!!!!!!!";
}
}
void DragWin::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
QString strX = QString::number(MediaServer::curWidget->pos().x());
QString strY = QString::number(MediaServer::curWidget->pos().y());
QString strW = QString::number(MediaServer::curWidget->rect().width());
QString strH = QString::number(MediaServer::curWidget->rect().height());
emit sendParamSignals(strX, strY, strW, strH);
// winxEdit->setText(strX);
// winyEdit->setText(strY);
// winwEdit->setText(strW);
// winhEdit->setText(strH);
MediaServer::m_bIsMousePressed = false;
qDebug() << "PainterGragh 鼠标释放 点击窗口 ==== " << event->globalPos() << " m_bIsMouseMove== " << m_bIsMouseMove << endl;
if(m_bIsMouseMove) {
QTcpClient *tcp= QTcpClient::getInstance();
int wid = MediaServer::curWidget->getId();
qDebug() << "窗口移动位置 wid ==== " << wid << endl;
QString str1 = "{\"srxApi\":\"setWinRect\",\"param\":{\"wid\":"+ QString::number(wid) +",\"winx\":"+ strX +",\"winy\":"+ strY +",\"winw\":"+ strW +",\"winh\":"+ strH +"}}";
tcp->sendJson(str1);
qDebug() << "窗口移动位置 发送指令 ==== " << event->globalPos() << m_bIsMouseMove << endl;
}
m_bIsMouseMove = false;
}
}
void DragWin::mouseMoveEvent(QMouseEvent *event)
{
if(MediaServer::m_bIsMousePressed && (event->buttons() == Qt::LeftButton))
{
m_bIsMouseMove = true;
// qDebug() << "PainterGragh 小窗口拖拽 event->type()==== " << event->type() << this << endl;
// qDebug() << "PainterGragh 鼠标拖拽 pEvent->globalPos() ==== " << event->globalPos();
// qDebug() << "PainterGragh 鼠标拖拽 m_qMousePoint ==== " << MediaServer::m_qMousePoint;
// MediaServer::curWidget = qobject_cast<QWidget*>(watched);
MediaServer::curWidget = this;
int iL= event->globalPos().x() - MediaServer::m_qMousePoint.x();
int iT= event->globalPos().y() - MediaServer::m_qMousePoint.y();
iL <= 0 && (iL = 0);
iT <= 0 && (iT = 0);
MediaServer::curWidget->move(iL, iT);
QString strW = QString::number(MediaServer::curWidget->rect().width());
QString strH = QString::number(MediaServer::curWidget->rect().height());
emit sendParamSignals(QString::number(iL), QString::number(iT), strW, strH);
// winxEdit->setText(QString::number(iL));
// winyEdit->setText(QString::number(iT));
}
}
#ifndef DRAGWIN_H
#define DRAGWIN_H
#include <QWidget>
#include "paintergragh.h"
#include <QLineEdit>
#include <QMouseEvent>
#include <QPoint>
#include <QCursor>
#include <QRect>
#include "CJsonObject.hpp"
using namespace neb;
#define PADDING 2
class DragWin : public PainterGragh
{
Q_OBJECT
public:
explicit DragWin(QWidget *parent = nullptr);
public:
int winId;
int winZ;
int winX;
int winY;
int winW;
int winH;
int getId(){return winId;}
void setId(int val){
winId = val;
}
int getWinZ(){return winZ;}
void setWinZ(int val){
winZ = val;
}
int parseJSON(CJsonObject je);
signals:
public slots:
private:
bool m_bIsMouseMove = false;
bool isLeftPressDown;
QPoint dragPosition;
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
signals:
void sendParamSignals(QString x, QString y, QString w, QString h);
public:
//QLineEdit *winxEdit;
//QLineEdit *winyEdit;
//QLineEdit *winwEdit;
//QLineEdit *winhEdit;
};
#endif // DRAGWIN_H
//新建几行几列
void MediaServer::on_new_btn_clicked()
{
int line = ui->usrRow->text().toInt();
int col = ui->usrLine->text().toInt();
int winwVal = ui->winW->text().toInt();
int winhVal = ui->winH->text().toInt();
int winW = 100, winH = 100;
if(winwVal && winhVal) {
winW = winwVal;
winH = winhVal;
}
for (int i=0;i<line;i++) {
for (int j=0;j<col;j++) {
DragWin *widget = new DragWin(ui->widget_7);
// widget->winxEdit = ui->winX;//这个是指向PainterGragh
// widget->winyEdit = ui->winY;
// widget->winwEdit = ui->winW;
// widget->winhEdit = ui->winH;
widget->setGeometry(i*winW,j*winH,winW,winH);
widget->setStyleSheet("background:#fff;border:1px solid #ccc;margin:0;");
widget->show();
curWidget = widget;
qDebug() << "新建 curWidget==== " << curWidget << endl;
connect(widget, &DragWin::sendParamSignals, this, &MediaServer::winParamSlot);
QString strX = QString::number(curWidget->pos().x());
QString strY = QString::number(curWidget->pos().y());
QString strW = QString::number(winW);
QString strH = QString::number(winH);
ui->winX->setText(strX);
ui->winY->setText(strY);
ui->winW->setText(strW);
ui->winH->setText(strH);
}
}
}
//新建窗口时 绑定槽函数,点击方块和拖拽时更新 x/y/w/h
void MediaServer::winParamSlot(QString strX, QString strY, QString strW, QString strH)
{
ui->winX->setText(strX);
ui->winY->setText(strY);
ui->winW->setText(strW);
ui->winH->setText(strH);
}