按下Shift键(C++和Qt 5.8)时,垂直/水平直线完美

Perfectly Straight Vertical/Horizontal Line When Pressing the Shift Key (C++ and Qt 5.8)

本文关键字:垂直 水平 完美 Shift C++ Qt 按下      更新时间:2023-10-16

在一个名为EasyPaint的程序中按下shift键时,我正在执行一项任务,以实现一条完全笔直的垂直/水平线。我的代码中没有错误,但不幸的是,它对程序本身也没有任何影响。当我画一条线并按下shift键时,它绝对不会起任何作用。下面的代码是我的方法shiftPressEvent,我的另一个方法是Mod。我试着计算度数,试图指定线何时应该捕捉到垂直对齐或水平对齐,但很明显,它似乎没有达到预期的效果。如果另一双眼睛能够分析代码并找出问题所在,我将不胜感激。此外,如果需要任何进一步的信息,请在下面发表评论。我可以很容易地发布整个类的LineInstrument,但它有点长。

在LineInstrument.cpp中添加编辑前的方法

void LineInstrument::shiftPressEvent(QKeyEvent *event, ImageArea &imageArea){
if (imageArea.isPaint())
{
imageArea.setImage(mImageCopy);
double Y = mStartPoint.y() - mEndPoint.y();
double X = mStartPoint.x() - mEndPoint.x();
radianAngle = atan2(Y, X);
degreeAngle = radianAngle * 180 / atan(1) * 4;
if (isMod(event->key()))
{
if (abs(degreeAngle) >= 45 && abs(degreeAngle) <= 135)
{
mEndPoint.setX(mStartPoint.x());
}
else if (abs(degreeAngle) < 45 && abs(degreeAngle) > 135)
{
mEndPoint.setY(mStartPoint.y());
}
imageArea.update();
}
}
}
bool LineInstrument::isMod(int key){
if (key == Qt::Key_Shift)
{
return true;
}
return false;
}

编辑后在LineInstrument.cpp中添加方法

void LineInstrument::shiftPressEvent(QKeyEvent *event, ImageArea &imageArea)
{
if (imageArea.isPaint())
{
imageArea.setImage(mImageCopy);
double Y = mStartPoint.y() - mEndPoint.y();
double X = mStartPoint.x() - mEndPoint.x();
if (isMod(event->key()) && fabs(X) > fabs(Y))
{
mEndPoint.setY(mStartPoint.y());
paint(imageArea, false);
}
else if (isMod(event->key()) && fabs(Y) >= fabs(X))
{
mEndPoint.setX(mStartPoint.x());
paint(imageArea, false);
}
}
}
bool LineInstrument::isMod(int key)
{
if (key == Qt::Key_Shift)
{
return true;
}
return false;
}

编辑前的LineInstrument头文件

#ifndef LINEINSTRUMENT_H
#define LINEINSTRUMENT_H
#include "abstractinstrument.h"
#include <QtCore/QObject>
#include <QKeyEvent>
/**
* @brief Line instrument class.
*
*/
class LineInstrument : public AbstractInstrument
{
Q_OBJECT
public:
explicit LineInstrument(QObject *parent = 0);
void mousePressEvent(QMouseEvent *event, ImageArea &imageArea);
void mouseMoveEvent(QMouseEvent *event, ImageArea &imageArea);
void mouseReleaseEvent(QMouseEvent *event, ImageArea &imageArea);
void shiftPressEvent(QKeyEvent *event, ImageArea &imageArea);
bool isMod(int key);
protected:
void paint(ImageArea &imageArea, bool isSecondaryColor = false, bool additionalFlag = false);
private:
double radianAngle;
double degreeAngle;
};
#endif // LINEINSTRUMENT_H

编辑后的LineInstrument头文件

#ifndef LINEINSTRUMENT_H
#define LINEINSTRUMENT_H
#include "abstractinstrument.h"
#include <QtCore/QObject>
#include <QKeyEvent>
/**
* @brief Line instrument class.
*
*/
class LineInstrument : public AbstractInstrument
{
Q_OBJECT
public:
explicit LineInstrument(QObject *parent = 0);
void mousePressEvent(QMouseEvent *event, ImageArea &imageArea);
void mouseMoveEvent(QMouseEvent *event, ImageArea &imageArea);
void mouseReleaseEvent(QMouseEvent *event, ImageArea &imageArea);
void shiftPressEvent(QKeyEvent *event, ImageArea &imageArea);
bool isMod(int key);
protected:
void paint(ImageArea &imageArea, bool isSecondaryColor = false, bool additionalFlag = false);
};
#endif // LINEINSTRUMENT_H

问题的一部分是没有正确计算角度(度)。这条线并不像你想象的那样:

degreeAngle = radianAngle * 180 / atan(1) * 4;

这与相同

degreeAngle = 4 * radianAngle * 180 / atan(1);

您应该做的是通过如下操作为pi创建一个适当命名的常量:

const double kPi = atan(1.0) * 4.0;

您可能应该创建一个函数来将弧度转换为度数,如下所示:

double toDegrees(double radians)
{
return radians * 180.0 / kPi;
}

您还可以通过简单地比较x增量和y增量,更容易地确定是要水平捕捉还是垂直捕捉。如果X大于Y,则需要一条水平线,否则需要一条垂直线。像这样的东西应该可以做到:

if (fabs(X) > fabs(Y))
{
mEndPoint.setY(mStartPoint.y());
}
else
{
mEndPoint.setX(mStartPoint.x());
}

现在,这是否能解决您的问题取决于您的绘图实际是如何进行的。