我正在研究类似画家的应用程序。这个想法是有两个pixmaps。首先包含原始图像,由用户上传,第二个包含所有绘图并具有透明背景。要显示结果pixmaps将被组合并显示在QLabel中。这样做是这样的:
void ImageViewer::on_openAct_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open File"), QDir::currentPath());
if (!fileName.isEmpty()) {
QImage image(fileName);
if (image.isNull()) {
QMessageBox::information(this, tr("Image Viewer"),
tr("Cannot load %1.").arg(fileName));
return;
}
imageLabel->setPixmap(QPixmap::fromImage(image));
scaleFactor = 1.0;
objectpix.scaled(QSize(imageLabel->size()), Qt::KeepAspectRatio, Qt::FastTransformation);
objectpix.fill(Qt::transparent);
/.../
}
}
mFirstX = e->x()/scaleFactor+ scrollArea->horizontalScrollBar()->value()/scaleFactor;
mFirstY = (e->y() - 31)/scaleFactor+ scrollArea->verticalScrollBar()->value()/scaleFactor;
/.../
QPainter paint(&objectpix);
QPen PointPen (Qt::red);
PointPen.setWidth(5);
QBrush PointBrush (Qt::red,Qt::SolidPattern);
QPoint p1 = QPoint(mFirstX,mFirstY);
paint.setPen(PointPen);
paint.setBrush(PointBrush);
paint.drawEllipse(p1,2,2);
QPixmap p(*imageLabel->pixmap());
QPainter painter(&p);
painter.drawPixmap(imageLabel->rect(),objectpix,objectpix.rect());\
painter.end();
imageLabel->setPixmap(p);
但没有任何迹象表明这一点。如果我只显示第二个像素图(包含所有图纸并具有透明背景),它只显示透明的像素图,即我看到我的应用程序的背景。我究竟做错了什么?任何帮助表示赞赏。
不知怎的,我感觉OP descibes实际上应该是可能的......
......并亲自尝试。
这就是我得到的(testQPixmapCombine.cc
):
#include <QtWidgets>
class Label: public QLabel {
private:
QPixmap _qPixmap;
public:
Label(QWidget *pQParent = nullptr):
QLabel(pQParent)
{ }
virtual ~Label() = default;
Label(const Label&) = delete;
Label& operator=(const Label&) = delete;
void setPixmap(const QPixmap &qPixmap)
{
_qPixmap = qPixmap;
QLabel::setPixmap(_qPixmap = qPixmap);
}
protected:
virtual void mousePressEvent(QMouseEvent *pQEvent) override;
};
void Label::mousePressEvent(QMouseEvent *pQEvent)
{
// clear overlay
QPixmap qPixmapDraw(_qPixmap.size());
qPixmapDraw.fill(QColor(0, 0, 0, 0));
// draw red circle at mouse coordinates
{ QPainter qPainter(&qPixmapDraw);
qPainter.setPen(QPen(Qt::red, 2));
qPainter.drawEllipse(pQEvent->pos(), 20, 20);
}
// combine pixmaps
QPixmap qPixmapComp = _qPixmap;
{ QPainter qPainter(&qPixmapComp);
qPainter.drawPixmap(0, 0, qPixmapDraw);
}
QLabel::setPixmap(qPixmapComp);
pQEvent->accept();
}
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// load image file
const QImage qImg("cat.png");
QPixmap qPixmap;
qPixmap.convertFromImage(qImg);
// setup UI
Label qWin;
qWin.setWindowTitle(QString::fromUtf8("Combine Pixmaps"));
qWin.setPixmap(qPixmap);
qWin.show();
// runtime loop
return app.exec();
}
和相应的Qt项目(testQPixmapCombine.pro
):
SOURCES = testQPixmapCombine.cc
QT += widgets
我在cygwin64编译和测试:
$ qmake-qt5 testQPixmapCombine.pro
$ make && ./testQPixmapCombine
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQPixmapCombine.o testQPixmapCombine.cc
g++ -o testQPixmapCombine.exe testQPixmapCombine.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
Qt Version: 5.9.4
在我点击螺栓后,图像底部有一个小红圈。
我必须承认,关于我的代码,我甚至不需要额外的QPixmap
。 (我想证明使用透明像素图的绘图按照预期工作 - 根据OP的问题。)
Label::mousePressEvent()
的这种替代实现会产生相同的效果:
void Label::mousePressEvent(QMouseEvent *pQEvent)
{
QPixmap qPixmapDraw(_qPixmap);
// draw red circle at mouse coordinates
{ QPainter qPainter(&qPixmapDraw);
qPainter.setPen(QPen(Qt::red, 2));
qPainter.drawEllipse(pQEvent->pos(), 20, 20);
}
QLabel::setPixmap(qPixmapDraw);
pQEvent->accept();
}
请注意,我考虑过在Kerndog73's answer中提出的潜在问题:用额外的一对花括号确定QPainter qPainter
,我获得了与文档中提到的相同的效果。 QPainter::end()
:
结束绘画。释放绘画时使用的任何资源。您通常不需要调用它,因为它是由析构函数调用的。
(通过 - 分钟。)
您必须先完成objectpix
上的绘图,然后才能与其他画家一起使用。绘制椭圆后调用paint.end()
。在您破坏画家或使用end()
明确完成绘画之前,不会修改像素图。