Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How determine from which child a mousePressEvent came

How determine from which child a mousePressEvent came

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 4.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    buckler
    wrote on last edited by
    #1

    Hello,
    I have a QBboxLayout in which I place a variable number of child widgets. After adding them, the user can either left- or right-click individuals in order to process the specific child that they pressed. When a child is added, its widget is created and I keep information about it in a list which reflects what is in the QVBoxLayout at any given time.

    My first attempt at determining which child is clicked was to make an explicit connect when the child is made, passing an additional parameter to a slot handling the the mousePressEvent in addition to the event itself. But this caused a different signature for the slot and I could not get it to be recognized, resulting in "no such signal" errors at run time.

    My next thought, attempted in the code below, is to try to tell which child caused the event within the handler itself. Here is an extract of the code which creates children in the first place, the handler, and finally classes for the class with the list as well as a class with the information the user desires to interact with for each child:

    void seriesSurvey::on_addSeriesButton_clicked()
    {
    imageSeries newSeries;

    for (int i = 0; i < 1; ++i) { // here there is one series at a time, however, code will also be used as template for reading in as many series' as are initiailized in the workItemListEntry
    QVBoxLayout *seriesWidget;
    QWidget *seriesThumb;

    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        sizePolicy.setHorizontalStretch(0);
        sizePolicy.setVerticalStretch(0);
        sizePolicy.setHeightForWidth(ui->workingView->sizePolicy().hasHeightForWidth());
        QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    seriesWidget = new QVBoxLayout();
    seriesWidget->setObjectName(QStringLiteral("seriesWidget"));
    seriesWidget->setSizeConstraint(QLayout::SetFixedSize);
    seriesWidget->setContentsMargins(-1, 3, -1, -1);
    seriesThumb = new QWidget(ui->scrollAreaWidgetContents);
    seriesThumb->setObjectName(QStringLiteral("seriesThumb"));
    sizePolicy.setHeightForWidth(seriesThumb->sizePolicy().hasHeightForWidth());
    seriesThumb->setSizePolicy(sizePolicy);
    seriesThumb->setMinimumSize(QSize(0, 150));
    seriesThumb->setMaximumSize(QSize(16777215, 200));
    
    seriesWidget->addWidget(seriesThumb);
    
    ui->seriesSetBox->insertLayout(0, seriesWidget);
    
    // Earlier (now abandoned) attempts to get child-specific mouse events
    //seriesThumb->setContextMenuPolicy(Qt::CustomContextMenu);
    //connect(seriesThumb, SIGNAL(mousePressEvent(QMouseEvent *)), this, SLOT(mousePressEvent(QMouseEvent *, &seriesSet.at(0)))); 
    
    // and add this to the list for later access
    seriesSet.insert(0, newSeries);
    

    }

    // this is my attempt to determine which child it is within the handler itself, so that the signature wouldn't be changed
    void seriesSurvey::mousePressEvent(QMouseEvent *event)
    {
    // determine which one the user clicked
    for (int i=0; i < seriesSet.size(); i++) {
    if (this == seriesSet.at(i))
    break;
    }
    if (i == seriesSet.size())
    QErrorMessage *error = new QErrorMessage (this);
    error->showMessage(tr("Error: Can't find current session item."));
    return;
    }

    if (event->button() == Qt::LeftButton)
    qDebug() << seriesSet[i]->getSeriesUID() << " series selected";
    else if (event->button() == Qt::RightButton)
    qDebug() << seriesSet[i]->getSeriesUID() << " series properties";
    else
    qDebug() << "something else";
    }

    /****************************************************** SERIES PACKAGE ***************************************************************
    *

    • The series package comprises the following related classes:
      • imageSeries:
      • seriesSurvey (in namepace Ui) (subclassed from QWidget): the main class with the series set as a whole and the methods to
    •  display and interact with it
      
      1.      imageSeries
        
    •             |
      
      1.     seriesSurvey
        

    **************************************************************************************************************************************/

    class imageSeries
    {

    public:
    imageSeries();
    imageSeries(const QString &type, const QString &UID);

    const QString getSeriesFolder() const { return seriesFolder; };
    void setSeriesFolder(QString folder) { seriesFolder = folder; };

    private:
    QString seriesFolder;
    QWidget *seriesThumb;
    };

    namespace Ui {
    class seriesSurvey;
    }

    class seriesSurvey : public QWidget
    {
    Q_OBJECT

    QList<imageSeries> seriesSet;

    public:
    explicit seriesSurvey(QWidget *parent = 0);
    ~seriesSurvey();

    QList<imageSeries> &imageSeriesSet() { return seriesSet; };
    void mousePressEvent(QMouseEvent *event);

    private slots:
    void on_addSeriesButton_clicked();

    private:
    Ui::seriesSurvey *ui;
    };

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      Im not sure 100% what you are trying but the
      QMouseEvent event
      has sender info. Its base class QObject but you can cast it.
      QPushButton
      button = dynamic_cast<QPushButton*>(sender());
      if (button) // is not null it could be cast
      else
      http://doc.qt.io/qt-5/qsignalmapper.html

      also lets you have many objects that call same SLOT and you can then find out whom called.

      1 Reply Last reply
      0
      • B Offline
        B Offline
        buckler
        wrote on last edited by
        #3

        Thank you! I did try to access sender(), with an updated handler:
        void seriesSurvey::mousePressEvent(QMouseEvent event)
        {
        // determine which one the user clicked
        qDebug() << qobject_cast<const QWidget
        >(this->sender());

        int i;
        for (i=0; i < seriesSet.size(); i++) {
        if (qobject_cast<const QWidget*>(this->sender()) == seriesSet.at(i).getSeriesThumb())
        break;
        }
        if (i == seriesSet.size()) {
        QErrorMessage *error = new QErrorMessage (this);
        error->showMessage(tr("Error: Can't find current session item."));
        return;
        }

        if (event->button() == Qt::LeftButton)
        qDebug() << seriesSet[i].getSeriesUID() << " series selected";
        else if (event->button() == Qt::RightButton)
        qDebug() << seriesSet[i].getSeriesUID() << " series properties";
        else
        qDebug() << "something else";
        }

        Unfortunately, my initial qDegug() reveals that it always comes back as 0x0. Perhaps I have expressed it incorrectly?

        Additionally, I did look at QSignalMapper. I see that it says "This class collects a set of parameterless signals, and re-emits them with integer, string or widget parameters corresponding to the object that sent the signal." The part about re-emitting them with a widget sounds very much to my need, however, the fact that it only does so with parameterless signals would not be helpful; I also need which button it was that was used.

        So I am still stuck!
        Andy

        mrjjM 1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          An event handler is not a slot so there's no sender. What you can use is an event filter (see installEventFilter). With it you know what object received the event and you also have the event to analyze and react on.

          On a side note, qobject_cast is to be used when cast QObject derived classes

          Hope it helps

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • B buckler

            Thank you! I did try to access sender(), with an updated handler:
            void seriesSurvey::mousePressEvent(QMouseEvent event)
            {
            // determine which one the user clicked
            qDebug() << qobject_cast<const QWidget
            >(this->sender());

            int i;
            for (i=0; i < seriesSet.size(); i++) {
            if (qobject_cast<const QWidget*>(this->sender()) == seriesSet.at(i).getSeriesThumb())
            break;
            }
            if (i == seriesSet.size()) {
            QErrorMessage *error = new QErrorMessage (this);
            error->showMessage(tr("Error: Can't find current session item."));
            return;
            }

            if (event->button() == Qt::LeftButton)
            qDebug() << seriesSet[i].getSeriesUID() << " series selected";
            else if (event->button() == Qt::RightButton)
            qDebug() << seriesSet[i].getSeriesUID() << " series properties";
            else
            qDebug() << "something else";
            }

            Unfortunately, my initial qDegug() reveals that it always comes back as 0x0. Perhaps I have expressed it incorrectly?

            Additionally, I did look at QSignalMapper. I see that it says "This class collects a set of parameterless signals, and re-emits them with integer, string or widget parameters corresponding to the object that sent the signal." The part about re-emitting them with a widget sounds very much to my need, however, the fact that it only does so with parameterless signals would not be helpful; I also need which button it was that was used.

            So I am still stuck!
            Andy

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @buckler said:
            Sorry, my bad. Was thinking of on_addSeriesButton_clicked .
            If the child widgets are of mixed types , then as @SGaist says, eventfilter
            is the way to go.

            1 Reply Last reply
            0
            • B Offline
              B Offline
              buckler
              wrote on last edited by
              #6

              mrjj and SGaist,
              Hats off to you for helping me fix this. The event handler did it. mrjj, far from "my bad", I also learned from your suggestion. In this case however - as seems often from my short experience, SGaist gets the master prize.

              Thanks to all on the forum,
              Andy

              B 1 Reply Last reply
              0
              • B buckler

                mrjj and SGaist,
                Hats off to you for helping me fix this. The event handler did it. mrjj, far from "my bad", I also learned from your suggestion. In this case however - as seems often from my short experience, SGaist gets the master prize.

                Thanks to all on the forum,
                Andy

                B Offline
                B Offline
                buckler
                wrote on last edited by
                #7

                @buckler
                I said event handler, but meant that the event filter did it :-).

                mrjjM 1 Reply Last reply
                0
                • B buckler

                  @buckler
                  I said event handler, but meant that the event filter did it :-).

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  @buckler
                  Yeah, that was clear even wrong word :)

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved