История изменений
Исправление kamre, (текущая версия) :
Для Ъ: начиная с 4.8 Qt криво рисует линии.
В целочисленных действительно стал криво рисовать. А вот в qreal - наоборот получше вроде. Чем не подходит преобразовывать в qreal и рисовать?
Вроде нормально рисуется:
#include <QApplication>
#include <QLabel>
#include <QCheckBox>
#include <QPainter>
#include <QMouseEvent>
#include <QLayout>
class DrawLine: public QWidget {
Q_OBJECT
public:
DrawLine() : size(11), scale(60), radius(5), active(-1), hover(-1),
image(size, size, QImage::Format_RGB32), round(false) {
int sz = size*scale;
setMinimumSize(sz, sz);
int half = sz/2;
pts[0] = QPoint(half/2, half);
pts[1] = QPoint(half*3/2, half);
renderLine();
setMouseTracking(true);
}
void emitCoords() {
QString str;
if (round) {
QPoint p0 = roundCoords(0);
QPoint p1 = roundCoords(1);
str.sprintf("P0: (%d, %d) P1: (%d, %d)", p0.x(), p0.y(), p1.x(), p1.y());
} else {
QPointF p0 = coords(0);
QPointF p1 = coords(1);
str.sprintf("P0: (%.2f, %.2f) P1: (%.2f, %.2f)", p0.x(), p0.y(), p1.x(), p1.y());
}
emit coordsUpdated(str);
}
public slots:
void setRound(bool round) {
this->round = round;
renderLine();
}
signals:
void coordsUpdated(QString coords);
protected:
virtual void paintEvent(QPaintEvent*) {
QPainter p(this);
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
QRgb cur = image.pixel(i, j);
p.fillRect(i*scale, j*scale, scale, scale, QColor(cur));
}
}
p.setPen(Qt::lightGray);
int sz = size*scale;
for (int i = 0; i < size; ++i) {
int x = i*scale;
p.drawLine(x, 0, x, sz);
p.drawLine(0, x, sz, x);
}
p.setRenderHint(QPainter::Antialiasing);
p.setPen(Qt::blue);
p.drawLine(pts[0], pts[1]);
p.setPen(Qt::NoPen);
for (int i = 0; i < 2; ++i) {
p.setBrush(i == hover ? Qt::yellow : Qt::blue);
p.drawEllipse(pts[i], radius, radius);
}
}
virtual void mousePressEvent(QMouseEvent *event) {
if (active == -1 && event->button() == Qt::LeftButton) {
int current = index(event->pos());
if (current != -1)
active = current;
}
}
virtual void mouseReleaseEvent(QMouseEvent *event) {
if (active != -1 && event->button() == Qt::LeftButton) {
active = -1;
}
}
virtual void mouseMoveEvent(QMouseEvent *event) {
if (active != -1) {
pts[active] = event->pos();
renderLine();
}
int current = index(event->pos());
if (current != hover) {
hover = current;
update();
}
}
private:
QPointF coords(int idx) {
return QPointF(pts[idx])/scale;
}
QPoint roundCoords(int idx) {
return (coords(idx) - QPointF(0.5, 0.5)).toPoint();
}
int index(QPoint p) {
for (int i = 0; i < 2; ++i) {
if (QLineF(p, pts[i]).length() <= radius)
return i;
}
return -1;
}
void renderLine() {
image.fill(qRgb(255, 255, 255));
QPainter p(&image);
p.setPen(Qt::red);
if (round) {
p.drawLine(roundCoords(0), roundCoords(1));
} else {
p.drawLine(coords(0), coords(1));
}
emitCoords();
update();
}
int size;
int scale;
int radius;
int active;
int hover;
QImage image;
QPoint pts[2];
bool round;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget widget;
QLabel label;
QCheckBox round("Round coords");
DrawLine draw;
QObject::connect(&draw, SIGNAL(coordsUpdated(QString)), &label, SLOT(setText(QString)));
QObject::connect(&round, SIGNAL(toggled(bool)), &draw, SLOT(setRound(bool)));
QGridLayout layout;
layout.addWidget(&round, 0, 0);
layout.addWidget(&label, 0, 1);
layout.addWidget(&draw, 1, 0, 1, 2);
layout.setColumnStretch(1, 1);
widget.setLayout(&layout);
widget.show();
draw.emitCoords();
return app.exec();
}
#include "main.moc"
Исходная версия kamre, :
Для Ъ: начиная с 4.8 Qt криво рисует линии.
В целочисленных действительно стал криво рисовать. А вот в qreal - наоборот получше вроде. Чем не подходит округлять в qreal и рисовать?
Вроде нормально рисуется:
#include <QApplication>
#include <QLabel>
#include <QCheckBox>
#include <QPainter>
#include <QMouseEvent>
#include <QLayout>
class DrawLine: public QWidget {
Q_OBJECT
public:
DrawLine() : size(11), scale(60), radius(5), active(-1), hover(-1),
image(size, size, QImage::Format_RGB32), round(false) {
int sz = size*scale;
setMinimumSize(sz, sz);
int half = sz/2;
pts[0] = QPoint(half/2, half);
pts[1] = QPoint(half*3/2, half);
renderLine();
setMouseTracking(true);
}
void emitCoords() {
QString str;
if (round) {
QPoint p0 = roundCoords(0);
QPoint p1 = roundCoords(1);
str.sprintf("P0: (%d, %d) P1: (%d, %d)", p0.x(), p0.y(), p1.x(), p1.y());
} else {
QPointF p0 = coords(0);
QPointF p1 = coords(1);
str.sprintf("P0: (%.2f, %.2f) P1: (%.2f, %.2f)", p0.x(), p0.y(), p1.x(), p1.y());
}
emit coordsUpdated(str);
}
public slots:
void setRound(bool round) {
this->round = round;
renderLine();
}
signals:
void coordsUpdated(QString coords);
protected:
virtual void paintEvent(QPaintEvent*) {
QPainter p(this);
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
QRgb cur = image.pixel(i, j);
p.fillRect(i*scale, j*scale, scale, scale, QColor(cur));
}
}
p.setPen(Qt::lightGray);
int sz = size*scale;
for (int i = 0; i < size; ++i) {
int x = i*scale;
p.drawLine(x, 0, x, sz);
p.drawLine(0, x, sz, x);
}
p.setRenderHint(QPainter::Antialiasing);
p.setPen(Qt::blue);
p.drawLine(pts[0], pts[1]);
p.setPen(Qt::NoPen);
for (int i = 0; i < 2; ++i) {
p.setBrush(i == hover ? Qt::yellow : Qt::blue);
p.drawEllipse(pts[i], radius, radius);
}
}
virtual void mousePressEvent(QMouseEvent *event) {
if (active == -1 && event->button() == Qt::LeftButton) {
int current = index(event->pos());
if (current != -1)
active = current;
}
}
virtual void mouseReleaseEvent(QMouseEvent *event) {
if (active != -1 && event->button() == Qt::LeftButton) {
active = -1;
}
}
virtual void mouseMoveEvent(QMouseEvent *event) {
if (active != -1) {
pts[active] = event->pos();
renderLine();
}
int current = index(event->pos());
if (current != hover) {
hover = current;
update();
}
}
private:
QPointF coords(int idx) {
return QPointF(pts[idx])/scale;
}
QPoint roundCoords(int idx) {
return (coords(idx) - QPointF(0.5, 0.5)).toPoint();
}
int index(QPoint p) {
for (int i = 0; i < 2; ++i) {
if (QLineF(p, pts[i]).length() <= radius)
return i;
}
return -1;
}
void renderLine() {
image.fill(qRgb(255, 255, 255));
QPainter p(&image);
p.setPen(Qt::red);
if (round) {
p.drawLine(roundCoords(0), roundCoords(1));
} else {
p.drawLine(coords(0), coords(1));
}
emitCoords();
update();
}
int size;
int scale;
int radius;
int active;
int hover;
QImage image;
QPoint pts[2];
bool round;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget widget;
QLabel label;
QCheckBox round("Round coords");
DrawLine draw;
QObject::connect(&draw, SIGNAL(coordsUpdated(QString)), &label, SLOT(setText(QString)));
QObject::connect(&round, SIGNAL(toggled(bool)), &draw, SLOT(setRound(bool)));
QGridLayout layout;
layout.addWidget(&round, 0, 0);
layout.addWidget(&label, 0, 1);
layout.addWidget(&draw, 1, 0, 1, 2);
layout.setColumnStretch(1, 1);
widget.setLayout(&layout);
widget.show();
draw.emitCoords();
return app.exec();
}
#include "main.moc"