2016-02-04 5 views
0

Я создал приложение Image Viewer, которое открывает и сохраняет изображение и загружает изображение на QLabel, затем я создал ScrollArea для прокрутки больших изображений, на моем втором шаге я пытаюсь нарисовать прямоугольник выделения, чтобы выбрать конкретный суб область, шаги, которые я предпринял для рисования прямоугольника выбора следующим образом:Как рисовать прямоугольник выбора на QScrollArea?

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; 
} 

и это скриншот для моего приложения

enter image description here

ответ

0

Как я могу нарисовать прямоугольник выбора на QScrollArea?

Вам нужно QRubberBand, которые должны быть непосредственно применены к ui->imageLabel виджета, который используется для отображения изображения, которое требуется для прокрутки. Независимо от того, следует ли перегрузить QLabel для ui->imageLabel, это вопрос реализации. Пожалуйста, см. example для событий мыши, которые, конечно, лучше применимы к классу изображений ярлыков.

Насколько я понимаю, на основе кода вы использовали Qt Designer? Это усложняет переопределение класса этикеток, но вы можете либо не использовать файл .ui, либо использовать event filter для захвата всех событий для данного объекта.

То, что у вас есть в настоящее время, может быть окончательно отполировано настолько, чтобы быть хорошим для фактического использования, конечно. Для вас это намного больше. Вы можете избежать перегрузки 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); 
} 
+0

Можете ли вы объяснить больше, что я должен изменить в своем коде? Я пытался использовать QRubberBand, но это не сработало. – Sunny

+0

Я добавил отредактированный образец из ссылки QRubberBand. Из моего предыдущего опыта, который сработал. – AlexanderVX

+0

это работает !! : D спасибо – Sunny