qtdrawingselectionrubber-band

QRubberBand on a definite label


Strange things happening: I need to use rubberBand on a label. Here's my code:

    QRubberBand *rubberBand;
    QPoint mypoint;

void MainWindow::mousePressEvent(QMouseEvent *event){

    mypoint = event->pos();
    rubberBand = new QRubberBand(QRubberBand::Rectangle, ui->label_2);//new rectangle band
    rubberBand->setGeometry(QRect(mypoint, ui->label_2->size()));
    rubberBand->show();
}

void MainWindow::mouseMoveEvent(QMouseEvent *event){
    rubberBand->setGeometry(QRect(mypoint, event->pos()).normalized());//Area Bounding
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event){
    rubberBand->hide();// hide on mouse Release
    rubberBand->clearMask();
}

everything works but there's only one trouble - rubberBound starts to paint a little bit lower then coursor set around 100-150px.

What am I doing wrong ?


Solution

  • The event->pos() is in a different coordinate system than that of your label, and your rubberband.

    http://qt-project.org/doc/qt-4.8/qwidget.html#mapFrom

    http://qt-project.org/doc/qt-4.8/qwidget.html#mapFromGlobal

    http://qt-project.org/doc/qt-4.8/qwidget.html#mapFromGlobal

    http://qt-project.org/doc/qt-4.8/application-windows.html

    http://qt-project.org/doc/qt-4.8/qwidget.html#geometry-prop

    http://qt-project.org/doc/qt-4.8/qwidget.html#rect-prop

    You need to map the event->pos() into a different coordinate system to compensate for the offset.

    EDIT: Here is an example.

    // In your constructor set rubberBand to zero.
    rubberBand = 0;
    
    void MainWindow::mousePressEvent(QMouseEvent *event){
    
        mypoint = ui->label->mapFromGlobal(this->mapToGlobal(event->pos()));
        // mypoint = ui->label->mapFrom(this, event->pos());
        // mypoint = this->mapTo(ui->label, event->pos());
        if(rubberBand == 0) // You should add this to not have a memory leak
            rubberBand = new QRubberBand(QRubberBand::Rectangle, ui->label_2);//new rectangle band
        rubberBand->setGeometry(QRect(mypoint, ui->label_2->size()));
        rubberBand->show();
    }
    

    In the QRubberBand description it shows how it would be implemented if it was being used on the widget whose mouseEvents it is triggered with. Since you are using it on a different widget from another widgets mouse events, you have to map the coordinates.

    Hope that helps.