Search code examples
c++qt4qt5qtwidgets

‘virtual bool QAbstractScrollArea::eventFilter(QObject*, QEvent*)’ is protected


I tried to find the answer to this one with google but nothing has born fruit. I'm in the process of converting an app from Qt4 to Qt5. This application compiled perfectly in Qt4 but when I try to compile against Qt5 now it's giving me this permission error. Since this class's status is protected in both versions I am having a hard time understanding what I need to change.

This compile issue has been replicated on a few different Ubuntu installs (including wsl) but I haven't tried in Fedora yet.

Here's a subset of the class

#include <QWidget>
#include <QEvent>
#include <QTableWidget>
#include <QItemDelegate>
#include <QModelIndex>
#include <QSize>
#include <qdialog.h>
#include <qcombobox.h>
#include "ui_pegs_page.h"
#include <string>

class EGS_ConfigReader;
class QProcess;
class PEGS_RunOutput;
class QTableWidget;

struct Element {
  int   Z;
  std::string symbol;
 float  aw;
 float  Iev;
 float  rho;
};

const int n_element = 100;

extern Element element_data[];

class TableEventHandler : public QObject {
    Q_OBJECT
public:
    TableEventHandler(QTableWidget *parent);
protected:
    bool eventFilter(QObject *o, QEvent *e);
private:
    QStringList itemCopy;
    QList<QTableWidgetSelectionRange> copyRange;
};

Edit:

Here's the method that has issues.

TableEventHandler::TableEventHandler(QTableWidget *parent) :
  QObject(parent) {
  if( parent == 0 )
   qFatal("TableEventHandler::TableEventHandler: parent can not be null!");
}


bool TableEventHandler::eventFilter(QObject *o, QEvent *e) {
  if( !o ) qWarning("TableEventHandler::eventFilter called with 0 object?");
  if( QString(o->metaObject()->className()) != tr("QTableWidget") ) {
#ifdef EI_DEBUG
      qDebug("Only QTableWidget objects accepted! Returning!");
#endif
      return false;
  }
  QTableWidget *to = (QTableWidget *)o;
  if( e->type() == QEvent::KeyPress ) {
    QKeyEvent *ke = (QKeyEvent*)e;
    if(ke->matches(QKeySequence::Copy) ){
       QString cellText; itemCopy.clear(); copyRange.clear();
       QList<QTableWidgetSelectionRange> ts = to->selectedRanges();
       if(!ts.isEmpty()) {
          for ( int irow = ts.first().topRow(); irow <= ts.first().bottomRow(); irow++){
               for ( int icol = ts.first().leftColumn(); icol <= ts.first().rightColumn(); icol++){
                   QTableWidgetItem *w = to->item(irow,icol);
                   if(w) cellText = w->text();
                   if ( !cellText.isEmpty() ){
                      itemCopy << cellText;
                   }
                   else
                      itemCopy << " ";
               }
          }
          copyRange = ts;
          //cout << itemCopy.join(", ").toLatin1().data() << endl;
       }
       else {
            QTableWidgetItem *w = to->item(to->currentRow(), to->currentColumn());
            if (w) cellText = w->text();
            if ( !cellText.isEmpty() )
                 itemCopy << cellText;
            else itemCopy << "";
       }
       return true;
    }
    else if(ke->matches(QKeySequence::Paste) && !itemCopy.isEmpty() && !copyRange.isEmpty()){
       QList<QTableWidgetSelectionRange> cs = to->selectedRanges();
       int top = cs.first().topRow(), left = cs.first().leftColumn(), icount = 0;
       QTableWidgetSelectionRange ts = QTableWidgetSelectionRange(
                                       top , left,
                                       top  + copyRange.first().rowCount()-1,
                                       left + copyRange.first().columnCount()-1);
       for ( int irow = ts.topRow(); irow <= ts.bottomRow(); irow++){
         for ( int icol = ts.leftColumn(); icol <= ts.rightColumn(); icol++){
             if ( ++icount <= itemCopy.size() )
                to->setItem(irow, icol, new QTableWidgetItem(itemCopy[icount-1]));
                to->setItem(irow, icol, new QTableWidgetItem(itemCopy[icount-1]));
         }
       }
       return true;
    }
    else if(ke->matches(QKeySequence::Cut) ){
       QString cellText; itemCopy.clear(); copyRange.clear();
       QList<QTableWidgetSelectionRange> ts = to->selectedRanges();
       if(!ts.isEmpty()) {
         for (int irow = ts.first().topRow(); irow <= ts.first().bottomRow(); irow++) {
           for(int icol = ts.first().leftColumn(); icol <= ts.first().rightColumn(); icol++) {
               QTableWidgetItem *w = to->item(irow,icol);
               if(w) cellText = w->text();
               if ( !cellText.isEmpty() ){
                  itemCopy << cellText;
               }
               else
                  itemCopy << "";
               to->setItem(irow,icol,0);
           }
         }
         copyRange = ts;
         //cout << itemCopy.join(", ").toLatin1().data() << endl;
       }
       return true;
    }
    else if(ke->matches(QKeySequence::Delete) ){
       QList<QTableWidgetSelectionRange> ts = to->selectedRanges();
       if(!ts.isEmpty()) {
         for (int irow = ts.first().topRow(); irow <= ts.first().bottomRow(); irow++) {
           for(int icol = ts.first().leftColumn(); icol <= ts.first().rightColumn(); icol++) {
               to->setItem(irow,icol,0);
           }
         }
       }
       return true;
    }
    else
        to->eventFilter(o, e);

  }
  return false;
}

Solution

  • You're accessing the protected QAbstractScrollArea::eventFilter(QObject*, QEvent*) method either

    1. from a method of a class which does not inherit from QAbstractScrollArea (most likely), or
    2. from a method of some other class which is not a friend of QAbstractScrollArea (not likely), or
    3. from a some function which is not a friend of QAbstractScrollArea (not likely).

    Note that TableEventHandler inherits directly from QObject and not from QAbstractScrollArea. So in case you're trying to call QAbstractScrollArea::eventFilter(QObject*, QEvent*) from one of the methods of TableEventHandler, then you get that error.

    EDIT: Looking at your edited answer, I see that you're calling

    to->eventFilter(o, e);
    

    in TableEventHandler::eventFilter(QObject *o, QEvent *e) where QTableWidget *to = (QTableWidget *)o;. The programmer probably meant for TableEventHandler::eventFilter not to filter the respective event at that point. The method should then instead just return false to pass control to any other event filters installed later on that object.