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 to emit signal back to a subclassed SqlTableModel

How to emit signal back to a subclassed SqlTableModel

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 656 Views
  • 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.
  • M Offline
    M Offline
    MH24
    wrote on 27 Apr 2023, 11:49 last edited by
    #1

    Bit of a chicken and egg problem here.
    My viewfaculty.cpp uses a subclassed QSqlTableModel so that a row in a dynamically created QTableView can only be edited when a corresponding dynamic button is clicked.
    See viewfacultycustomsqlmodel.h where I reimplement flags:

     virtual Qt::ItemFlags flags(const QModelIndex& index) const{
            Qt::ItemFlags flags;
            flags = QSqlTableModel::flags(index);
           
            if(index.row()==0 )
            {flags |= Qt::ItemIsEditable;
                return flags;
                }
            return (QSqlTableModel::flags(index) & ~Qt::ItemIsEditable);
        }
    

    Instead of index.row() == 0 (which works perfectly) I want index.row() == clicked_row which will use clicked_row an integer that was sent with signal emitted from viewfaculty.cpp on button click.

    That signal is void signal_clickedRow(int) and I do emit signal_clickedRow(i) in viewfaculty.cpp upon button click to send the index of the button (and the corresponding row) that is i.
    But how to catch it?
    If I try include viewfaculty.h in viewfacultycustomsqlmodel.h so that I can declare an instance of the class ViewFaculty in its header file through ViewFaculty *viewfac = new Viewfaculty and do a connect in viewfacultycustomsqlmodel.cpp like this:

    connect(viewfac,SIGNAL(signal_clickedRow(int)),this,SLOT(receivedFromViewFac(int)))
    

    I obviously get infinite connections to MySQL database and it runs into an infinite loop. This is because both the classes are including each other's header files. viewfaculty.h includes viewfacultyustomsqlmodel.h so that flags can be reimplemented and that custom table model instantiated there. But to do the other way communication, that is send signal from viewfaculty.cpp to viewfacultycustomsqlmodel.h the latter needs the former's header file.
    (plus the slot in viewfacultycustomsqlmodel.cpp will need a way to generate a clicked_row integer to be used in flags. I dont know how to do that either).
    So any idea how to do it? I hope what I've done and what I am trying to do is clear. I dont want to add the i value into database to be read in another class. I want to do it through Qt. Kindly help me out.

    J P 2 Replies Last reply 27 Apr 2023, 12:01
    0
    • M MH24
      27 Apr 2023, 11:49

      Bit of a chicken and egg problem here.
      My viewfaculty.cpp uses a subclassed QSqlTableModel so that a row in a dynamically created QTableView can only be edited when a corresponding dynamic button is clicked.
      See viewfacultycustomsqlmodel.h where I reimplement flags:

       virtual Qt::ItemFlags flags(const QModelIndex& index) const{
              Qt::ItemFlags flags;
              flags = QSqlTableModel::flags(index);
             
              if(index.row()==0 )
              {flags |= Qt::ItemIsEditable;
                  return flags;
                  }
              return (QSqlTableModel::flags(index) & ~Qt::ItemIsEditable);
          }
      

      Instead of index.row() == 0 (which works perfectly) I want index.row() == clicked_row which will use clicked_row an integer that was sent with signal emitted from viewfaculty.cpp on button click.

      That signal is void signal_clickedRow(int) and I do emit signal_clickedRow(i) in viewfaculty.cpp upon button click to send the index of the button (and the corresponding row) that is i.
      But how to catch it?
      If I try include viewfaculty.h in viewfacultycustomsqlmodel.h so that I can declare an instance of the class ViewFaculty in its header file through ViewFaculty *viewfac = new Viewfaculty and do a connect in viewfacultycustomsqlmodel.cpp like this:

      connect(viewfac,SIGNAL(signal_clickedRow(int)),this,SLOT(receivedFromViewFac(int)))
      

      I obviously get infinite connections to MySQL database and it runs into an infinite loop. This is because both the classes are including each other's header files. viewfaculty.h includes viewfacultyustomsqlmodel.h so that flags can be reimplemented and that custom table model instantiated there. But to do the other way communication, that is send signal from viewfaculty.cpp to viewfacultycustomsqlmodel.h the latter needs the former's header file.
      (plus the slot in viewfacultycustomsqlmodel.cpp will need a way to generate a clicked_row integer to be used in flags. I dont know how to do that either).
      So any idea how to do it? I hope what I've done and what I am trying to do is clear. I dont want to add the i value into database to be read in another class. I want to do it through Qt. Kindly help me out.

      J Offline
      J Offline
      JonB
      wrote on 27 Apr 2023, 12:01 last edited by
      #2

      @MH24
      I'm sorry I don't understand all of what you have typed. But there is a very simple rule: models should NEVER know about views. Hence a model's .cpp should never be allowed/want/need to include a view's .h. The other way round is OK: a view can include the .h for a specific model type.

      Anything a view might pass to a model must be in model terms, not view. So if there something about "a clicked row number" in the view, turn it into whatever as a model row number before passing to model code. The model must never ask the view about what row was clicked.

      Your connect() of a viewfac signal to a model slot should never be done in the model --- as you have done with this for the slot receiver. It must be done either from the view (which knows about the model) or from elsewhere which knows about both the view and the model.

      M 1 Reply Last reply 27 Apr 2023, 12:12
      2
      • M MH24
        27 Apr 2023, 11:49

        Bit of a chicken and egg problem here.
        My viewfaculty.cpp uses a subclassed QSqlTableModel so that a row in a dynamically created QTableView can only be edited when a corresponding dynamic button is clicked.
        See viewfacultycustomsqlmodel.h where I reimplement flags:

         virtual Qt::ItemFlags flags(const QModelIndex& index) const{
                Qt::ItemFlags flags;
                flags = QSqlTableModel::flags(index);
               
                if(index.row()==0 )
                {flags |= Qt::ItemIsEditable;
                    return flags;
                    }
                return (QSqlTableModel::flags(index) & ~Qt::ItemIsEditable);
            }
        

        Instead of index.row() == 0 (which works perfectly) I want index.row() == clicked_row which will use clicked_row an integer that was sent with signal emitted from viewfaculty.cpp on button click.

        That signal is void signal_clickedRow(int) and I do emit signal_clickedRow(i) in viewfaculty.cpp upon button click to send the index of the button (and the corresponding row) that is i.
        But how to catch it?
        If I try include viewfaculty.h in viewfacultycustomsqlmodel.h so that I can declare an instance of the class ViewFaculty in its header file through ViewFaculty *viewfac = new Viewfaculty and do a connect in viewfacultycustomsqlmodel.cpp like this:

        connect(viewfac,SIGNAL(signal_clickedRow(int)),this,SLOT(receivedFromViewFac(int)))
        

        I obviously get infinite connections to MySQL database and it runs into an infinite loop. This is because both the classes are including each other's header files. viewfaculty.h includes viewfacultyustomsqlmodel.h so that flags can be reimplemented and that custom table model instantiated there. But to do the other way communication, that is send signal from viewfaculty.cpp to viewfacultycustomsqlmodel.h the latter needs the former's header file.
        (plus the slot in viewfacultycustomsqlmodel.cpp will need a way to generate a clicked_row integer to be used in flags. I dont know how to do that either).
        So any idea how to do it? I hope what I've done and what I am trying to do is clear. I dont want to add the i value into database to be read in another class. I want to do it through Qt. Kindly help me out.

        P Offline
        P Offline
        Pl45m4
        wrote on 27 Apr 2023, 12:07 last edited by
        #3

        @MH24 said in How to emit signal back to a subclassed SqlTableModel:

        This is because both the classes are including each other's header files

        This is already bad per se.

        You have to overthink your design/structure (have a look at the tipps @JonB has posted above)


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        1 Reply Last reply
        2
        • J JonB
          27 Apr 2023, 12:01

          @MH24
          I'm sorry I don't understand all of what you have typed. But there is a very simple rule: models should NEVER know about views. Hence a model's .cpp should never be allowed/want/need to include a view's .h. The other way round is OK: a view can include the .h for a specific model type.

          Anything a view might pass to a model must be in model terms, not view. So if there something about "a clicked row number" in the view, turn it into whatever as a model row number before passing to model code. The model must never ask the view about what row was clicked.

          Your connect() of a viewfac signal to a model slot should never be done in the model --- as you have done with this for the slot receiver. It must be done either from the view (which knows about the model) or from elsewhere which knows about both the view and the model.

          M Offline
          M Offline
          MH24
          wrote on 27 Apr 2023, 12:12 last edited by
          #4

          @JonB
          Got it. So I took the connect to a third class, unimain.cpp that is hidden from view when viewfaculty.cpp is showing its view. I included both the above headers and did this:

          connect(viewFaculty,SIGNAL(signal_clickedRow(int)),viewfacultycustomsqltablemodel,SLOT(receivedFromViewFac(int)));
          

          There are no infinite calls to database now. Signal is being received neatly but the row isnt being allowed for editing. let me see.

          J 1 Reply Last reply 27 Apr 2023, 12:17
          0
          • M MH24
            27 Apr 2023, 12:12

            @JonB
            Got it. So I took the connect to a third class, unimain.cpp that is hidden from view when viewfaculty.cpp is showing its view. I included both the above headers and did this:

            connect(viewFaculty,SIGNAL(signal_clickedRow(int)),viewfacultycustomsqltablemodel,SLOT(receivedFromViewFac(int)));
            

            There are no infinite calls to database now. Signal is being received neatly but the row isnt being allowed for editing. let me see.

            J Offline
            J Offline
            JonB
            wrote on 27 Apr 2023, 12:17 last edited by
            #5

            @MH24
            Yep that looks good.

            While you are on a roll, do yourself a favor! Get rid of all these old-style SIGNAL/SLOT() connect() statements and use the New Signal Slot Syntax which replaced it a decade ago.

            connect(viewFaculty, &ViewClass::signal_clickedRow, viewfacultycustomsqltablemodel, &ModelClass::receivedFromViewFac);
            

            Now you get compile-time checking that slot exists and matches signal correctly.

            M 1 Reply Last reply 27 Apr 2023, 12:24
            1
            • J JonB
              27 Apr 2023, 12:17

              @MH24
              Yep that looks good.

              While you are on a roll, do yourself a favor! Get rid of all these old-style SIGNAL/SLOT() connect() statements and use the New Signal Slot Syntax which replaced it a decade ago.

              connect(viewFaculty, &ViewClass::signal_clickedRow, viewfacultycustomsqltablemodel, &ModelClass::receivedFromViewFac);
              

              Now you get compile-time checking that slot exists and matches signal correctly.

              M Offline
              M Offline
              MH24
              wrote on 27 Apr 2023, 12:24 last edited by
              #6

              @JonB DId not know about that, thank you!

              1 Reply Last reply
              0
              • M MH24 has marked this topic as solved on 27 Apr 2023, 12:26
              • M MH24 referenced this topic on 3 May 2023, 04:59
              • M MH24 referenced this topic on 4 May 2023, 06:46
              • M MH24 referenced this topic on 5 May 2023, 10:05

              1/6

              27 Apr 2023, 11:49

              • Login

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