问题
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.
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