Qt: Emit same signal from one object but with different arguments; Slot distinguish by received argument

StackOverflow https://stackoverflow.com/questions/20523540

Frage

In C++ using opencv I capture an image and after processing the image I have four images: The original, a yellow, blue and green, threshold image. Finally these images get emitted from the ImageProcessing class:

Q_EMIT capturedImage(iImageOriginal);
Q_EMIT capturedImage(iImageYellowThreshold);
Q_EMIT capturedImage(iImageBlueThreshold);
Q_EMIT capturedImage(iImageGreenThreshold);

where iImage... is a QImage.

To display the images in the MainWindow class there is a slot that should display the "correct" image depending on the selected comboBox (cbSelectCameraImage) index:

void MainWindow::setImage(QImage iImage)
{
    if (ui->cbSelectCameraImage->currentText() == "Original Camera Image")
    {   
        // Here I need to set the corresponding image only if the 
        // signal cpaturedImage was emitted with argument iImageOriginal
        ui->lblCamera->setPixmap(QPixmap::fromImage(iImage));
    }
    else if (ui->cbSelectCameraImage->currentText() == "Yellow Threshold")
    {
        // Here I need to set the corresponding image only if the 
        // signal cpaturedImage was emitted with argument iImageYellowThreshold
        ui->lblCamera->setPixmap(QPixmap::fromImage(iImage));
    }
    else if (ui->cbSelectCameraImage->currentText() == "Blue Threshold")
    {
        ui->lblCamera->setPixmap(QPixmap::fromImage(iImage));
    }
    else if (ui->cbSelectCameraImage->currentText() == "Green Threshold")
    {
        ui->lblCamera->setPixmap(QPixmap::fromImage(iImage));
    }
}

where lblCamera is a QLabel

The main question is if there is a way to distinguish by the received argument? Or if there is a way to get the text iImageYellowThreshold somehow to use for setting the corresponding image.

I can think of using multiple signals to emit each image. Or to us a second argument in the capturedImage signal - int or enum - to distinguish the arguments. But I would like to know if there is a way to use only one signal and one argument?

War es hilfreich?

Lösung

Enum or integer as a second argument would work, or you can use QSignalMapper and multiple signals.

There is no way to distinguish by received argument since that received argument would be QImage in all cases, unless there is some information in QImage that would allow you to uniquely distinguish image type - such as image format, or color pallet that can be retrieved from QImage,

Andere Tipps

Your obsession with keeping it down to one signal is somewhat unnatural -- there's no reason for it in this case.

If you really wish, don't forget you're using C++. You can pass type information at runtime through polymorphism.

class ImageOriginal : public QImage {
  ImageOriginal(const QImage & img) : QImage(img) {}
};

class ImageYellowThreshold : public QImage {
  ImageYellowThreshold(const QImage & img) : QImage(img) {}
};

class Sender : public QObject {
  Q_OBJECT
public:
  Q_SIGNAL void signal(const QImage &);
  void test() {
    QImage img;
    emit signal(ImageOriginal(img));
};

class Receiver : public QObject {
  Q_OBJECT
public:
  Q_SLOT void slot(const QImage & image) {
    if (dynamic_cast<ImageOriginal*>(&image)) {
      // this is the original image
    }
    else if (dynamic_cast<ImageYellowThreshold*>(&image)) {
      // this is the yellow threshold image
    }
    else {
      // generic image
    }
  }
};

Proper answer here is:

  • CREATE 4 SEPARATE SIGNALS instead complicate your life.
  • Or add some value which will define what should be emitted and emit signal once with specific value.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top