0

In order to shrink the problem I made a small verifiable example of a small gui. If you would like to take a glance at the code you can see it here.

I have a specific string on a QLineEdit, this string is passed to a QListView via QPushButton as shown below. Those strings are choices of a QComboBox and they are very specific: 1) "[ INFO] Minimum Distance: 5", 2) "[ INFO] Minimum Distance: 10" and 3) "[ INFO] Minimum Distance: 15"

The problem: How can I detect the specific QString content inside a QListView in order to change the background color of a QGraphicsView?

For example if inside the QListView there is "[ INFO] Minimum Distance: 5", the color of the QGraphicsView should be red or if inside the QListView there is "[ INFO] Minimum Distance: 10", the color of the QGraphicsView should be yellow etc.

string

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mView = new QGraphicsView();
    mScene = new QGraphicsScene();
    ui->graphicsView->setScene(mScene);

    mText = new QGraphicsTextItem;
    mText->setPos(150,70);
    mScene->addText(tr("Boat outside alarm area"))->setDefaultTextColor(Qt::black);

    model = new QStringListModel();
    ui->listView->setModel(model);
    ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);

    changeColorDetection();

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::changeColorDetection()
{
    QColor red;
    QColor yellow;
    QColor green;

    // if [ INFO] Minimum Distance: 5 inside QListView
    // Than change color of the QGraphicsView background to red

    // if [ INFO] Minimum Distance: 10 inside QListView
    // Than change color of the QGraphicsView background to yellow

    QModelIndex index = ui->listView->currentIndex();
    QString itemText = index.data(Qt::DisplayRole).toString();
    if(itemText.startsWith("[ INFO] Minimum Distance: 10"))
    {
        ui->graphicsView->setStyleSheet("QGraphicsView {background-color: red}");
    }
}

void MainWindow::on_pushButton_clicked()
{
    QString str = ui->lineEdit->text();
    model->insertRow(model->rowCount());
    QModelIndex index = model->index(model->rowCount()-1);
    model->setData(index, str);
}


void MainWindow::on_comboBox_currentIndexChanged(const QString &arg1)
{
    QString list = ui->comboBox->currentText();
    ui->lineEdit->setText(list);
    Q_UNUSED(arg1)
}

mainwindow.h

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsTextItem>
#include <QStringListModel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void changeColorDetection();

private slots:
    void on_pushButton_clicked();
    void on_comboBox_currentIndexChanged(const QString &arg1);

private:
    Ui::MainWindow *ui;
    QGraphicsView *mView;
    QGraphicsScene *mScene;
    QGraphicsTextItem *mText;
    QStringListModel *model;

};
#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

In case you also would like to see the small .ui the code is below:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>555</width>
    <height>382</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout_2">
    <item row="0" column="0">
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <widget class="QGroupBox" name="groupBox">
        <property name="title">
         <string>Area</string>
        </property>
        <layout class="QGridLayout" name="gridLayout">
         <item row="0" column="0">
          <layout class="QHBoxLayout" name="horizontalLayout">
           <item>
            <widget class="QCheckBox" name="checkBoxRedArea">
             <property name="text">
              <string>Red area</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QCheckBox" name="checkBoxYellowArea">
             <property name="text">
              <string>Yellow Area</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QCheckBox" name="checkBoxGreenArea">
             <property name="text">
              <string>Green Area</string>
             </property>
            </widget>
           </item>
          </layout>
         </item>
         <item row="1" column="0">
          <layout class="QHBoxLayout" name="horizontalLayout_3">
           <item>
            <widget class="QPushButton" name="pushButton">
             <property name="text">
              <string>Add Message</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QLineEdit" name="lineEdit"/>
           </item>
           <item>
            <widget class="QComboBox" name="comboBox">
             <item>
              <property name="text">
               <string>Select Option Distance</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>[ INFO] Minimum Distance: 5</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>[ INFO] Minimum Distance: 10</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>[ INFO] Minimum Distance: 15</string>
              </property>
             </item>
             <item>
              <property name="text">
               <string>[ INFO] Minimum Distance: 20</string>
              </property>
             </item>
            </widget>
           </item>
          </layout>
         </item>
        </layout>
       </widget>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_2">
        <item>
         <widget class="QListView" name="listView"/>
        </item>
        <item>
         <widget class="QGraphicsView" name="graphicsView">
          <property name="styleSheet">
           <string notr="true">background-color: rgb(211, 215, 207);</string>
          </property>
         </widget>
        </item>
       </layout>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>555</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

What I have done so far:

I have been doinf a lot of research about this problem and came across this source which was useful but could not solve the problem, but in addition it seems to use a QModelIndex and I am not sure this is exactly what I need for this small project.

Also I read this source which was useful to establish and capture the specific and unique string but in terms of changing colors I could not solve that.

I also came across this which led me to give a try to the following:

void MainWindow::changeColorDetection()
{
    // if [ INFO] Minimum Distance: 5 inside QListView
    // Than change color of the QGraphicsView background
    QModelIndex index = ui->listView->currentIndex();
    QString itemText = index.data(Qt::DisplayRole).toString();
    if(itemText.startsWith("[ INFO] Minimum Distance: 10"))
    {
        QColor bg = ui->graphicsView->palette().background().color();
        ui->graphicsView->setStyleSheet(QString("background-color:") + bg.name(QColor::HexArgb));
    }
}

But also this last one did not result in any change in the background.

What am I missing? Thank you very much for pointing to the right direction for solving this issue.

Emanuele
  • 2,194
  • 6
  • 32
  • 71

1 Answers1

1

QGraphicsView background handling differs from other widgets where you might use stylesheets to define the background. Use ui->graphicsView->setBackgroundBrush() to change a simple background, or overload QGraphicsView::setBackground() for anything more complicated. In your case:

ui->graphicsView->setBackgroundBrush(QColor("red"))

See SVG color names for valid color names or use hex notation.

Regarding the dection of texts that lead to color changes, you need to be aware that a list model has multiple independent entries and you need to establish a rule for the color change. In your example, it is changed dependent on the currently selected item. Or do you want to change it based on the latest item, or any item? In these cases you might need to watch for signals when items are added and removed, and/or to search through all items. This is very easy using your model directly:

QStringList allStrings = model()->stringList();
QString last = allStrings.last();
// also have a look at QStringList::contains(), QStringList::lastOf()
ypnos
  • 50,202
  • 14
  • 95
  • 141
  • thanks for reading the question. Yes, I would like to change the color of the `QGraphicsView` background based on the last item detected on the `QListView`. – Emanuele Apr 28 '20 at 17:02
  • Then you can directly use the example code I provided and do `last.startsWith(...)`. – ypnos Apr 28 '20 at 17:19
  • Ok I see. Just to clarify: the example code you provided, I should use it inside the function `changeColorDetection()` and add related `connect SIGNAL + SLOT` inside constructor? – Emanuele Apr 28 '20 at 17:22
  • Perfect, thank you very much it works, see [here](https://i.imgur.com/aHpmnwK.png) – Emanuele Apr 28 '20 at 18:10
  • Nice! Thanks for the feedback. If you deem my answer helpful I suggest you accept it. – ypnos Apr 28 '20 at 20:32
  • I accepted your answer! Thanks again for the advise you gave me :). If you also think my question was clear please give me thumbs up :) have a great day! – Emanuele Apr 28 '20 at 20:43
  • You are right, I don't consider your question generally interesting as this is a very specific solution you developed, however I _did_ notice how much effort you put into making it a great question to answer. Actually made me take the time to answer it. – ypnos Apr 28 '20 at 21:41