How to change QGraphicsView background color based on specific QString content inside a QListView

淺唱寂寞╮ 提交于 2020-05-17 06:11:08

问题


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.


回答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()


来源:https://stackoverflow.com/questions/61485124/how-to-change-qgraphicsview-background-color-based-on-specific-qstring-content-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!