Results 1 to 5 of 5

Thread: QTableView and Color Editing

  1. #1
    Join Date
    Oct 2017
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default QTableView and Color Editing

    Hi there,

    I'm implementing editing functionality for a column in a QTableView that contains a color setting. The table in question contains a column that displays a color value. It looks as follows:

    PenColor before Edit.PNG

    This value should be made editable. After searching the internet for possible ways to accomplish that I decided for a solution that uses a QColorDialog. My current implementation looks as follows:

    In the constructor of the class that contains the QTableView (ui->graphsTbl) I added a connect statement that activates a slot method editGraphColor(QModelIndex) upon double click on an instance of the color column:

    Qt Code:
    1. connect(ui->graphsTbl, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(editGraphColor(QModelIndex)));
    To copy to clipboard, switch view to plain text mode 

    The slot method looks as follows:


    Qt Code:
    1. void MainWindow::editGraphColor(QModelIndex modelIx) {
    2. if (modelIx.column() != GraphsTableModel::COLUMNS::PEN_COLOR)
    3. return;
    4. QColor currColor = modelIx.model()->data(modelIx, Qt::BackgroundRole).value<QColor>();
    5. QColor color = QColorDialog::getColor(currColor, this, "Pick a color",
    6. QColorDialog::DontUseNativeDialog);
    7. if (color.isValid() && color != currColor)
    8. ui->graphsTbl->model()->setData(modelIx, color, Qt::BackgroundRole);
    9. }
    To copy to clipboard, switch view to plain text mode 

    First I filter out a double click on another column than the PEN_COLOR column. Then I retrieve the current color from the target color cell and pass it to the QColorDialog. After execution of the QColorDialog I pass the new color (in case it differs from the previous color) back to the model.

    In the table's model class (named GraphsTableModel and inheriting from QAbstractTableModel) I implemented the Qt::BackgroundRole for the "PEN_COLOR" column in the data(...) as well as setData(...) methods:


    Qt Code:
    1. QVariant GraphsTableModel::data(const QModelIndex &index, int role) const {
    2. if (!isIndexValid(index))
    3. return QVariant();
    4.  
    5. const Graph &graph(*mGraphs.at(index.row()));
    6. if (role == Qt::DisplayRole) {
    7. switch (index.column()) {
    8. case LEGEND:
    9. return graph.legend();
    10. case PEN_COLOR:
    11. return QString("Double Click to Change");
    12. [...]
    13. default:
    14. return QVariant();
    15. }
    16. } else if (role == Qt::EditRole) {
    17. switch (index.column()) {
    18. case LEGEND:
    19. return graph.legend();
    20. [...]
    21. default:
    22. return QVariant();
    23. }
    24. } else if (role == Qt::BackgroundRole) {
    25. if (index.column() == PEN_COLOR)
    26. return graph.penColor();
    27. else
    28. return QVariant();
    29. } else
    30. return QVariant();
    31. }
    32.  
    33. bool GraphsTableModel::setData(const QModelIndex& index, const QVariant& value, int role) {
    34. if (!isIndexValid(index))
    35. return false;
    36.  
    37. Graph &graph(*mGraphs.at(index.row()));
    38. if (role == Qt::EditRole) {
    39. switch(index.column()) {
    40. case LEGEND:
    41. graph.setLegend(value.toString());
    42. break;
    43. [...]
    44. default:
    45. return false;
    46. }
    47. } else if (role == Qt::BackgroundRole) {
    48. if (index.column() == PEN_COLOR)
    49. graph.setPenColor(value.value<QColor>());
    50. } else
    51. return false;
    52.  
    53. emit dataChanged(index, index);
    54. return true;
    55. }
    To copy to clipboard, switch view to plain text mode 

    There is some strange behavior with this code:

    1. After a double click on a cell in the "Pen Color" column the QColorDialog is shown. After having selected another color and clicked on the "OK" button the QColorDialog vanishes but immediately shows up again. Only after a click on the "OK" button in the reappeared dialog it is closed and does not show up again.

    2. The color cell for which I changed the color shows a white background and a text cursor (looks as if it were to store textual data and be in edit mode). After a mouse click on a position outside that cell it shows the new color and no text cursor anymore.

    I have no idea what I did wrong. I'd expect that after changing the color using the QColorDialog and having passed the new color value into the model the QTableView would update its display (triggered by the dataChanged(...) signal emitted at the end of the model's setData(...) method.

    And I'm a bit confused of the roles concept in Qt. I tried out what happens when I implement the Qt::EditRole for the PEN_COLOR column in the setData(...) method:

    Qt Code:
    1. [...]
    2. Graph &graph(*mGraphs.at(index.row()));
    3. if (role == Qt::EditRole) {
    4. switch(index.column()) {
    5. case LEGEND:
    6. graph.setLegend(value.toString());
    7. break;
    8. case PEN_COLOR:
    9. graph.setPenColor(value.value<QColor>());
    10. break;
    11. [...] default:
    12. return false;
    13. }
    14. } else if (role == Qt::BackgroundRole) {
    15. if (index.column() == PEN_COLOR)
    16. graph.setPenColor(value.value<QColor>());
    17. } else
    18. return false;
    19.  
    20. emit dataChanged(index, index);
    21. return true;
    22. }
    To copy to clipboard, switch view to plain text mode 

    but this did not change the behavior.
    Any helful hint on what I'm doing wrong would be highly appreciated.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTableView and Color Editing

    2. The color cell for which I changed the color shows a white background and a text cursor (looks as if it were to store textual data and be in edit mode). After a mouse click on a position outside that cell it shows the new color and no text cursor anymore.
    All table cells store text data. Single-clicking puts it into edit mode, in which case the table view creates a line edit over the cell into which the user types the new text. When the editor is closed (by clicking somewhere else), setData() will be called and the table updated with the new text, icon, background, etc. If you want to defeat this behavior, then you need to 1) install a delegate or 2) set the cell as non-editable.

    I don't know what's happening with your double-click behavior.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. The following user says thank you to d_stranz for this useful post:

    apatwork (7th December 2017)

  4. #3
    Join Date
    Oct 2017
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QTableView and Color Editing

    Hi,

    thanks a lot for your information. This sentence enlightened me:

    If you want to defeat this behavior, then you need to 1) install a delegate or 2) set the cell as non-editable.
    In fact, with my table's color column I'm not using the "standard" editing mechanism. My editor is the QColorDialog and it is started through the signal slot mechanism upon double click on a color cell in my table. Because of this I have to disable editing for the pen color column. This is done in the flags(...) method of the QTableView's model class (GraphsTableModel in my case). With this little change now the color cell is no longer in edit mode after I have changed its color using the QColorDialog.
    From my understanding I cannot use the QColorDialog in a delegate because the editor used in a delegate is meant for being placed in the cell's area.

    There's just one little issue left over: When double clicking on a cell it first gets selected (changes its background color to blue). Maybe this happens in response to the first click. After having changed the color (using the QColorDialog) the cell still is selected and therefore the new color is not yet visible. It becomes visible only after clicking somewhere else (this way unselecting the cell). At the moment I don't know how to get rid of that behavior.
    BTW, for me not a single click but a double click puts a cell into edit mode. Maybe this is platform specific behavior? I'm developing my application on Linux.

  5. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTableView and Color Editing

    You could try setting the flags to also exclude "selectable". This might prevent the cell from being highlighted. Or you could override the single-click event to handle the pen color cells and passing the event to the parent class for other cells.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  6. #5
    Join Date
    Oct 2017
    Posts
    18
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: QTableView and Color Editing

    Hi!

    Thanks a lot for your helpful hints. I tried both of them and in principle they do what they are meant for. But there are still some strange behaviors left over. Let's have a look at my table:

    QTableView with editors..jpg

    As can be seen on the screenshot there is a combination of different kinds of data in the table.

    • The first and 9th columns show text.
    • The second and third columns show boolean values.
    • The fourth column shows a color.
    • The 5th, 6th and 8th columns display icons and use QComboBoxes as editors.
    • The 7th shows text with a QComboBox as editor.


    All columns should be editable. I had already hard times to figure out how to make icons in columns using QComboBoxes as editors work. In principle now (almost) everything works but there are still some issues which I don't know how to handle:

    1. It must be possible to select a single row in my table and move it to a different row inside the table. With the columns changed to be no longer selectable it seems to be no longer possible to select a row. I have configured QAbstractItemView::SelectRows as selection behavior of the QTableView. It would be completely sufficient if I could perform a selection of a single row in the table by clicking on its vertical header cell. But I couldn't figure out yet how to accomplish this.

    2. The behavior in regard to editing is inconsistent between the different kinds of columns:

    • For the columns containing text editing can be started with either a double click or a click of the F2 key.
    • The check boxes can be toggled with single clicks
    • For the color cell editing now is started upon a single click
    • The columns showing icons require a double click to run their respective editors and the changed values are stored in the model just after a single click somewhere outside the table cells.


    I'd prefer a uniform behavior of all columns when they are to be edited, i.e. a single click or the F2 key clicked to activate the respective editor. So it would be great if I could configure this behavior somehow ...

    Thanks a lot for your patience!

Similar Threads

  1. QTableView: Edit without editing ability
    By nickla in forum Qt Programming
    Replies: 0
    Last Post: 23rd March 2011, 22:25
  2. QTableView how to do something on start/end editing
    By nickla in forum Qt Programming
    Replies: 2
    Last Post: 15th March 2011, 09:26
  3. problems editing rows in a QTableView
    By cyrfer in forum Qt Programming
    Replies: 4
    Last Post: 6th January 2010, 09:34
  4. Problem with editing QTableView
    By TimoSan in forum Qt Programming
    Replies: 0
    Last Post: 23rd November 2009, 11:46
  5. QTableView, editing, validating input
    By jml in forum Qt Programming
    Replies: 1
    Last Post: 24th July 2007, 01:57

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.