P
P
Philip Bondarev2017-09-23 17:39:13
Qt
Philip Bondarev, 2017-09-23 17:39:13

How to catch signal of overridden QGraphicsPixmapItem in main window slot?

There is a custom `QGraphicsView` , I catch mouse events in it to scale and pan the image. In `QGraphicsScene` there is a custom `QGraphicsPixmapItem` , in it, by `mousePressEvent` , pixel information is determined and a `pixelData` signal is emitted , which I want to catch by the main window:

void myPixItemX::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        if (event->button() != Qt::RightButton) {
            QPoint position(event->pos().x(), event->pos().y());
            QImage local_image = QImage(qImg_x);
            QColor *color = new QColor;
            pixel_color = color->fromRgb(local_image.pixel(position));
            if (pixel_color.isValid ()) {
                pixel_data (position.x (), position.y (), pixel_color.red (), pixel_color.green (), pixel_color.blue ());
            }

        }
    }

I read that if you override your `QGraphicsItem` , then you need to first inherit from `QObject` in the constructor and call the macro `Q_OBJECT` . I did this with my `QGraphicsPixmapItem` , it didn't seem to give any errors:
class myPixItemX : public QObject, public QGraphicsPixmapItem
    {
        Q_OBJECT
    public:
        myPixItemX(const QPixmap & pixmap, QGraphicsItem * parent = 0);
    // Ну и далее по списку, не буду тут все приводить...

However, the trouble came from where you don't expect it at all ...
When I tried to connect the signal of my `Pix` object to the slot in the main window
connect(ui->graphicsView->Pix, SIGNAL(pixel_data(int,int,int,int,int)),this , SLOT(color_pick(int,int,int,int,int)));

, outputs the following to the console:
QObject::connect: Cannot connect (null)::pixel_data(int,int,int,int,int) to MainWindow::color_pick(int,int,int,int,int)

As I understand it, at the time the signal-slot connection was created, the `Pix` object had not yet been created, since it is created after receiving the image via the serial port. I tried to create a `Pix` object when initializing the `QGraphicsView` object , then delete it via `scene->clear();` , when receiving an image, and put a new one in its place. Here is the code for setting the image to the scene:
void ImageViewer::setPixmapImage(QByteArray image_data, int image_width, int image_height, int image_resolution)
    {
        del_grid();
        scene->clear();
        w_img = image_width;
        h_img = image_height;
        zoom = 0;
        unsigned char data[image_resolution];
        memcpy(data, image_data.toStdString().c_str(), image_resolution);
        qImg = QImage(data, image_width, image_height, image_width, QImage::Format_Grayscale8);
        pixmap = QPixmap::fromImage(qImg);
        Pix = new myPixItemX(pixmap);
        Pix->setQImg_x (qImg);
        scene->addItem(Pix);
        scene->setSceneRect(0, 0, pixmap.size().width(), pixmap.size().height());
        this->fitInView();
    }

Now nothing swears, however, the signal does not reach the main window.
And in general, I wildly dislike this idea with a custom `QGraphicsPixmapItem` , in `PyQt5` , you can do this:
self._photo = QGraphicsPixmapItem(QPixmap(self.qImg))
    self._photo.mousePressEvent = self.pixelSelect
    self._scene.addItem(self._photo)

and on click within `QGraphicsPixmapItem` `self.pixelSelect` will be called , but is it possible to do this in `Qt` without creating extra classes?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
F
Fil, 2017-09-23
@Dogrtt

I don't think it can be solved without redefining QGraphicsPixmapItem. It is best to create myPixItemX once at the beginning and update its pixmap by calling setPixmap. As you yourself understood, connect must be written after the creation of the object. To fix your solution, just write:

Pix = new myPixItemX(pixmap);
Pix->setQImg_x (qImg);
scene->addItem(Pix);
connect(Pix, SIGNAL(pixel_data(int,int,int,int,int)),this , SLOT(color_pick(int,int,int,int,int)));

Or in a new way:
And one more thing: QGraphicsPixmapItem already inherits from QObject, so replace
on the
class myPixItemX : public QGraphicsPixmapItem

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question