繁体   English   中英

如何在QScrollArea上绘制选择矩形?

[英]How can I draw a selection rectangle on QScrollArea?

我创建了一个Image Viewer应用程序,该应用程序可打开并保存图像并将其加载到QLabel上,然后创建一个ScrollArea来滚动查看大图像,在第二步中,我试图绘制选择矩形以选择特定的子区域,我绘制选择矩形所采取的步骤如下:

1-我用PaintEvent绘制矩形。 2-我使用MouseEvent选择子区域。

问题是,当我运行代码时,可以在QWidget上绘制矩形,但不能在ScrollArea上绘制矩形。

这是我的代码:

在imageviewer.h中

class ImageViewer : public QWidget{
Q_OBJECT
public:
   explicit ImageViewer(QWidget *parent = 0);
   ~ImageViewer();
private:
   Ui::ImageViewer *ui;

private slots:
  void on_openButton_pressed();

  void on_saveButton_pressed();

private:
  QPixmap image;
  QImage *imageObject;
  bool selectionStarted;
  QRect selectionRect;
  QMenu contextMenu;

protected:
  void paintEvent(QPaintEvent *e);
  void mousePressEvent(QMouseEvent *e);
  void mouseMoveEvent(QMouseEvent *e);
  void mouseReleaseEvent(QMouseEvent *e);
};

这是imageviewer.cpp

ImageViewer::ImageViewer(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ImageViewer)
{
    ui->setupUi(this);
    ui->scrollArea->setWidget(ui->imageLabel);
}

打开和保存功能:

void ImageViewer::on_openButton_pressed()
{
    QString imagePath = QFileDialog::getOpenFileName(this, tr("Open File") , "" ,
                                                 tr("JPEG (*.jpg *.jpeg);;PNG (*.png);;BMP (*.bmp)"));

    imageObject = new QImage();
    imageObject->load(imagePath);

    image = QPixmap::fromImage(*imageObject);

    ui->imageLabel->setPixmap(image);
    ui->imageLabel->adjustSize();

}

void ImageViewer::on_saveButton_pressed()
{
    QString imagePath = QFileDialog::getSaveFileName(this, tr("Save File") , "" ,
                                                 tr("JPEG (*.jpg *.jpeg);;PNG (*.png);;BMP (*.bmp)"));

    *imageObject = image.toImage();
    imageObject->save(imagePath);
}

绘画和鼠标事件功能:

void ImageViewer::paintEvent(QPaintEvent *e){
    QWidget::paintEvent(e);
    QPainter painter(this);
    painter.setPen(QPen(QBrush(QColor(0,0,0,180)),1,Qt::DashLine));
    painter.setBrush(QBrush(QColor(255,255,255,120)));
    painter.drawRect(selectionRect);
}

void ImageViewer::mousePressEvent(QMouseEvent *e){
    if(e->button() == Qt::RightButton){
        if(selectionRect.contains(e->pos()))
            contextMenu.exec(this->mapToGlobal(e->pos()));
    }
    else{
        selectionStarted = true;
        selectionRect.setTopLeft(e->pos());
        selectionRect.setBottomRight(e->pos());
    }
}

void ImageViewer::mouseMoveEvent(QMouseEvent *e){
    if(selectionStarted){
        selectionRect.setBottomRight(e->pos());
        repaint();
    }
}

void ImageViewer::mouseReleaseEvent(QMouseEvent *e){
    selectionStarted = false;
}

这是我的应用程序的屏幕截图

在此处输入图片说明

如何在QScrollArea上绘制选择矩形?

您需要QRubberBand ,它应该直接应用于ui->imageLabel小部件, ui->imageLabel小部件用于显示要滚动的图像。 是否应为ui->imageLabel重载QLabel是实现的问题。 请参见有关鼠标事件的示例 ,当然最好将其应用于标签图像类。

我从代码的外观上了解到您使用Qt Designer吗? 这使覆盖该标签类变得复杂,但是您不能使用.ui文件或使用事件过滤器来捕获给定对象的所有事件。

当然,您当前拥有的东西可以最终抛光到足以适合实际使用的程度。 这只会为您付出更多的努力。 您可以避免paintEvent等重载,关键是在需要应用的地方直接应用正确的方法。

// the example applied to authors code as requested
class MyImageLabel : public QLabel
{
public:
   explicit MyImageLabel(QWidget *parent = 0) : QLabel(parent), rubberBand(0) {}
private:
   QRubberBand* rubberBand;
   QPoint origin;

   void mousePressEvent(QMouseEvent *event);
   void mouseMoveEvent(QMouseEvent *event);
   void mouseReleaseEvent(QMouseEvent *event)
};

void MyImageLabel::mousePressEvent(QMouseEvent *event)
{
    origin = event->pos();
    if (!rubberBand)
        rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
    rubberBand->setGeometry(QRect(origin, QSize()));
    rubberBand->show();
}

void MyImageLabel::mouseMoveEvent(QMouseEvent *event)
{
    rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}

void MyImageLabel::mouseReleaseEvent(QMouseEvent *event)
{
    rubberBand->hide();
    // determine selection, for example using QRect::intersects()
    // and QRect::contains().
}

ImageViewer::ImageViewer(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ImageViewer)
{
    ui->setupUi(this);
    // resolve this better than:
    delete ui->imageLabel; // you already have the QLabel object here?
    ui->imageLabel = new MyImageLabel;
    ui->scrollArea->setWidget(ui->imageLabel);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM