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. [Solved] - QTableView - custom selection indicator (QRubberBand)
Forum Updated to NodeBB v4.3 + New Features

[Solved] - QTableView - custom selection indicator (QRubberBand)

Scheduled Pinned Locked Moved General and Desktop
17 Posts 2 Posters 7.5k Views 1 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.
  • M Offline
    M Offline
    maximus
    wrote on last edited by
    #5

    May be related to this warning: I get a bunch when I launch my program, haven't found the cause :

    @QPaintDevice::metrics: Device has no metric information@

    [Edit: this error what due to bad code here :
    for (int i=0; i<ui->tableView->colorCount(); i++)
    I simply misread colorCount for columnCount


    Free Indoor Cycling Software - https://maximumtrainer.com

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

      Aren't you drawing the rect above the text ?

      The metrics error is indeed surprising, what OS are you running on ?

      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
      0
      • M Offline
        M Offline
        maximus
        wrote on last edited by
        #7

        Hi,

        I am using Windows 8.1 x64 Enterprise

        I want to draw 2 object ;
        1- Rectangle highlighting with my row(s) selections
        2- Text showing a number at the right side of this rectangle (this one is not showing even if I comment the first object

        You can see my current interface here :
        https://www.dropbox.com/s/puzz9jwx09fwyp9/interface111.png
        What is missing is the black box where I need to draw text

        I updated my current QRubberBand paintEvent up here


        Free Indoor Cycling Software - https://maximumtrainer.com

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

          Since you are using the event rect which probably is the current QRubberBand geometry, painting on the top right corner makes you paint outside your widget

          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
          0
          • M Offline
            M Offline
            maximus
            wrote on last edited by
            #9

            You are right, the text is not painting because it is outside of the rectangle, I tried with this code and I can paint part of the text. Now is there a possibility to draw outside of the event.rect ? If not, I'm thinking maybe add a dummy column at the far right that will serve as place to draw the text. not really clean but could work...

            Current result with code below :
            https://www.dropbox.com/s/kumzp59opq9vuhg/currentREsult.png

            @void myRubberBand::paintEvent(QPaintEvent *event)
            {
            QRect rec1(event->rect());

            // qDebug() << "-----------------\nRECT ORIGINAL" << rec1;
            QStylePainter painter(this);
            QStyleOptionRubberBand option;
            initStyleOption(&option);

            QPen pen(Qt::red, 2);
            pen.setStyle(Qt::SolidLine);
            //    painter.setBrush(Qt::transparent);
            painter.setPen(pen);
            
            /// Find the middle right area of rectangle
            QPointF pointMiddleRight(rec1.center());
            pointMiddleRight.setX(pointMiddleRight.x() + 280);
            painter.drawText(pointMiddleRight, "abc");
            painter.drawRect(rec1);
            

            }@


            Free Indoor Cycling Software - https://maximumtrainer.com

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

              No there's not.

              Another way to do it, is to add a transparent (mouse event and color transparent) widget over your table view and do all the painting there.

              Or a second rubber band for the text part that you keep in sync with the original

              Or make the rubber band larger to also have the space to write the text.

              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
              0
              • M Offline
                M Offline
                maximus
                wrote on last edited by
                #11

                All good solutions, working perfectly!, Qt is very flexible
                Thanks again SGaist


                Free Indoor Cycling Software - https://maximumtrainer.com

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  maximus
                  wrote on last edited by
                  #12

                  Hey it's me again, I know I dragged this post a lot maybe I should start a new :)

                  Just wondering if something like this would be possible :
                  https://www.dropbox.com/s/xhczf5cg7pu8fxw/editableQRubberBand.png
                  (Editable QComboBox inside the QRubberBand)

                  I know how to draw the text, but not sure the editable QcomboBox is possible? Painting possible, but finding where the signals of the QComboBox is coming from?, maybe giving a unique name to the QComboBox, just tell me if you foresee this as possible before I waste too much time, thanks!


                  Free Indoor Cycling Software - https://maximumtrainer.com

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

                    Contextual menu ?

                    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
                    0
                    • M Offline
                      M Offline
                      maximus
                      wrote on last edited by
                      #14

                      Contextual menu? This is a right click menu right? IMO this doesn't really feel natural for this function, maybe for removing, copying rows I will use this but for what I need I would like a separate widget that is always displaying inside the QTableView, one widget per Repeat box, like shown in the pic. Not sure it is possible, I can draw it inside the QRubberBand, but it would be static and not usable afterwards. Still trying to use my imagination but I have limited Qt experience :/


                      Free Indoor Cycling Software - https://maximumtrainer.com

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

                        Yes and you have a point. Then you could have a QComboBox as member of your QRubberBand and handle its position yourself

                        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
                        0
                        • M Offline
                          M Offline
                          maximus
                          wrote on last edited by
                          #16

                          Hi SGaist,
                          Finally I used the solution of a custom QWidget over the QTableView, I needed a layout and it's easier to manage:

                          Here is the result interface :
                          https://www.dropbox.com/s/40osxyrdgxkuaf6/finalUi.png

                          I post the code in the next post if someone wants to do something similar
                          <Thread Solved for real now!>

                          Thank you


                          Free Indoor Cycling Software - https://maximumtrainer.com

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            maximus
                            wrote on last edited by
                            #17

                            RepeatWidget :
                            @RepeatWidget::RepeatWidget(QWidget *parent) :
                            QWidget(parent),
                            ui(new Ui::RepeatWidget)
                            {
                            ui->setupUi(this);

                            id = 0;
                            firstRow = 0;
                            lastRow = 0;
                            numberRepeat = 0;
                            

                            }

                            void RepeatWidget::on_pushButton_delete_clicked()
                            {
                            emit deleteSignal(id);
                            }

                            void RepeatWidget::on_comboBox_repeat_currentIndexChanged(const QString &arg1)
                            {
                            this->numberRepeat = arg1.toInt();
                            emit updateSignal(id);
                            }@

                            ParentUiClass with QListView:

                            @WorkoutCreator::~WorkoutCreator()
                            {
                            delete ui;
                            qDeleteAll(lstRepeatWidget);
                            lstRepeatWidget.clear();
                            }

                            WorkoutCreator::WorkoutCreator(QWidget *parent) : QWidget(parent), ui(new Ui::WorkoutCreator)
                            {
                            ui->setupUi(this);

                            [...]

                            connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
                                    this, SLOT(tableViewSelectionChanged(QItemSelection,QItemSelection)));
                            
                            totalWidthColumms = 0;
                            for (int i=0; i<ui->tableView->colorCount(); i++) {
                                totalWidthColumms += ui->tableView->columnWidth(i);
                            }
                            
                            ui->pushButton_delete->setEnabled(false);
                            ui->pushButton_copy->setEnabled(false);
                            ui->pushButton_repeat->setEnabled(false);
                            

                            }

                            void WorkoutCreator::tableViewSelectionChanged(QItemSelection selected, QItemSelection deselected) {

                            /// default behavior = disabled
                            ui->pushButton_delete->setEnabled(false);
                            ui->pushButton_copy->setEnabled(false);
                            ui->pushButton_repeat->setEnabled(false);
                            

                            // QModelIndexList lstIndex = selected.indexes();
                            QModelIndexList lstIndex = ui->tableView->selectionModel()->selectedRows();
                            qDebug() << lstIndex.size();

                            if (lstIndex.size() < 1) {
                                return;
                            }
                            
                            ui->pushButton_delete->setEnabled(true);
                            ui->pushButton_copy->setEnabled(true);
                            
                            QModelIndex firstIndex = lstIndex.at(0);
                            QModelIndex lastIndex = lstIndex.at(lstIndex.size()-1);
                            
                            
                            /// --- Check All overlappign possibilities (see if we can enable repeat button)
                            foreach (RepeatWidget *wid, lstRepeatWidget) {
                            
                                if (firstIndex.row() >= wid->firstRow && firstIndex.row() <= wid->lastRow )  {
                                    qDebug() << "1 REFUSE";
                                    return;
                                }
                            
                                if (lastIndex.row() <= wid->lastRow && lastIndex.row() >= wid->firstRow)  {
                                    qDebug() << "2 REFUSE";
                                    return;
                                }
                                if (firstIndex.row() < wid->firstRow && lastIndex.row() > wid->lastRow)  {
                                    qDebug() << "2 REFUSE";
                                    return;
                                }
                            }
                            
                            ui->pushButton_repeat->setEnabled(true);
                            

                            }

                            void WorkoutCreator::on_pushButton_repeat_clicked()
                            {

                            QModelIndexList lstIndex = ui->tableView->selectionModel()->selectedRows();
                            
                            if (lstIndex.size() < 1) {
                                return;
                            }
                            
                            QModelIndex firstIndex = lstIndex.at(0);
                            QModelIndex lastIndex = lstIndex.at(lstIndex.size()-1);
                            
                            QRect recFirstSelection(ui->tableView->visualRect(firstIndex));
                            QRect recLastSelection(ui->tableView->visualRect(lastIndex));
                            QRect rectCompleteSelection(recFirstSelection.topLeft(), recLastSelection.bottomRight() );
                            rectCompleteSelection.setWidth(totalWidthColumms);
                            
                            
                            RepeatWidget *repeatWidget = new RepeatWidget(ui->tableView->viewport());
                            repeatWidget->id = idRepeatWidget;
                            repeatWidget->firstRow = firstIndex.row();
                            repeatWidget->lastRow = lastIndex.row();
                            repeatWidget->move(rectCompleteSelection.topLeft());
                            repeatWidget->resize(rectCompleteSelection.size().width() + 190, rectCompleteSelection.size().height());
                            repeatWidget->show();
                            
                            
                            connect(repeatWidget, SIGNAL(deleteSignal(int)), this, SLOT(deletedRepeatWidget(int)) );
                            connect(repeatWidget, SIGNAL(updateSignal(int)), this, SLOT(updatedRepeatWidget(int)) );
                            
                            
                            /// Add widget to QList
                            idRepeatWidget ++;
                            lstRepeatWidget.append(repeatWidget);
                            

                            }

                            void WorkoutCreator::on_pushButton_add_clicked()
                            {
                            intervalModel->insertRow(intervalModel->rowCount());
                            }

                            void WorkoutCreator::on_pushButton_copy_clicked()
                            {

                            QModelIndexList lstIndex = ui->tableView->selectionModel()->selectedRows();
                            
                            foreach (QModelIndex index,  lstIndex) {
                                qDebug() << "going to copy row:" << index.row();
                                intervalModel->copyRows(index.row());
                            }
                            

                            }

                            void WorkoutCreator::on_pushButton_delete_clicked()
                            {

                            QModelIndexList lstIndex = ui->tableView->selectionModel()->selectedRows();
                            
                            if (lstIndex.size() < 1) {
                                return;
                            }
                            
                            int startRow = lstIndex.at(0).row();
                            intervalModel->removeRows(startRow, lstIndex.size(), QModelIndex());
                            

                            }

                            void WorkoutCreator::deletedRepeatWidget(int id) {

                            qDebug() << "deletedRepeatWidget" << id;
                            
                            RepeatWidget *widgetToDelete;
                            /// Better way to delete without iterating over QList? Array worth it? small data set..
                            foreach (RepeatWidget *wid, lstRepeatWidget) {
                                if (wid->id == id) {
                                    wid->setVisible(false);
                                    widgetToDelete = wid;
                                    break;
                            
                                }
                            }
                            lstRepeatWidget.removeOne(widgetToDelete);
                            

                            }

                            void WorkoutCreator::updatedRepeatWidget(int id) {

                            qDebug() << "updatedRepeatWidget" << id;
                            /// TODO: update graph with new values
                            

                            }
                            @


                            Free Indoor Cycling Software - https://maximumtrainer.com

                            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