Может ли QListView обнаружить заданную c QString и, следовательно, автоматически запустить слот? - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть указанная c строка на QLineEdit, эта строка передается QListView через QPushButton. Эти строки являются вариантами QComboBox, и они очень точны c:

1) "[INFO] Минимальное расстояние: 5",

2) "[INFO] Минимальное расстояние : 10 "и

3)" [INFO] Минимальное расстояние: 15 "

Здесь отлично работающий минимальный проверяемый пример, если вам нужно его проверить.

В настоящее время я могу успешно изменить цвет QGraphicsView, но щелкнув или дважды щелкнув по QString, введенному в QListView.

. проблема: Как мне обнаружить указанное c QString содержимое внутри QListView, чтобы изменить цвет фона QGraphicsView? Что я имею в виду, я не хочу щелкать или дважды щелкать по записи QListView, но я бы хотел, чтобы QListView увидел строку «[INFO] Минимальное расстояние: 5» и поэтому изменил цвет QGraphicsView автоматически, без моего нажатия или двойного щелчка на записи QListView.

После того, как я "Go в слот", мой выбор следующий:

go_to_slot

Ниже рабочего кода MVE вы можете скопировать / вставить на свой компьютер, и он будет работать:

mainwindow.h

#include <QMainWindow>
#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();
    void updateListView();
    void updateListView(const QString & message);

private slots:
    void on_pushButton_clicked();
    void on_listView_entered(const QModelIndex &index);
    void on_listView_activated(const QModelIndex &index);

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

};
#endif // MAINWINDOW_H

основное окно. 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);

    QFont font;
    font.setPixelSize(10);
    font.setBold(false);
    font.setFamily("Calibri");

    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);

    emptyIndex();

    connect(ui->listView, SIGNAL(loggingUpdated()), this, SLOT(updateListView(const QString &)));
    connect(ui->graphicsView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(on_listView_activated(const QModelIndex &index)));
}

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


void MainWindow::updateListView(const QString & message)
{
    if(model->insertRow(model->rowCount())) {
        QModelIndex index = model->index(model->rowCount() - 1, 0);
        model->setData(index, message);
        ui->listView->scrollTo(index);
    }
}

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);
    ui->listView->scrollToBottom();
}

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

void MainWindow::on_listView_activated(const QModelIndex &index)
{
    QStringList allStrings = model->stringList();
    QString last = allStrings.last();
    if(last.startsWith("[ INFO] Minimum Distance: 5"))
    {
        ui->graphicsView->setBackgroundBrush(QColor(Qt::red));
    }
    else if(last.startsWith("[ INFO] Minimum Distance: 10"))
    {
        ui->graphicsView->setBackgroundBrush(QColor(Qt::yellow));
    }
    else if(last.startsWith("[ INFO] Minimum Distance: 15"))
    {
        ui->graphicsView->setBackgroundBrush(QColor(Qt::green));
    }
    Q_UNUSED(index)
}

РЕДАКТИРОВАТЬ 2

mainwindow.h

#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsTextItem>
#include <QStringListModel>
#include "listview.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void setGraphicViewColor(QColor c);

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

    ListView *myListView;

};
#endif // MAINWINDOW_H

основное окно. cpp

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

#include <QDebug>

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

    QFont font;
    font.setPixelSize(10);
    font.setBold(false);
    font.setFamily("Calibri");

    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);


    connect(ui->listView, SIGNAL(changeColor(QColor)), this, SLOT(setGraphicViewColor(QColor)));
}

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


void MainWindow::setGraphicViewColor(QColor c)
{
    qDebug() << "Update your graphicsView backgroundBrush" << c;
    ui->graphicsView->setBackgroundBrush(Qt::green);
}

listview.h

#ifndef LISTVIEW_H
#define LISTVIEW_H

#include <QListView>
#include <QStringListModel>

class ListView : public QListView
{
    Q_OBJECT
public:
    ListView(QWidget *parent = nullptr);

signals:
    void changeColor(QColor c);

protected:
    void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>()) override;

};

#endif // LISTVIEW_H

listview. cpp

#include "listview.h"

ListView::ListView(QWidget *parent)
    : QListView(parent)
{}

void ListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    QListView::dataChanged(topLeft, bottomRight, roles);
    /**
     * Assuming that you have just one item changed
     * So topLeft == bottomRight
     */
    if (topLeft.row() == model()->rowCount()-1){
        QString last = topLeft.data().toString();
        if(last.startsWith("[ INFO] Minimum Distance: 5")) {
            emit changeColor(Qt::red);
        } else if(last.startsWith("[ INFO] Minimum Distance: 10")) {
            emit changeColor(Qt::yellow);
        } else if(last.startsWith("[ INFO] Minimum Distance: 15")) {
            emit changeColor(Qt::green);
        }
    }
}

Ниже приведена ошибка и снимок экрана пользовательского интерфейса, который не обнаруживает событие изменения:

error

Вывод .ui :

list_view

Что я сделал до сих пор:

Я провел много исследований по этой проблеме и наткнулся на этот источник , который был полезен, но не мог решить проблему, но, кроме того, он, кажется, использует QModelIndex, и я не уверен, что это именно то, что мне нужно для этого небольшого проекта.

Также я прочитал этот источник , который был полезен для установки sh и захвата указанных c и уникальной строки, но в терминах Я не мог решить эту проблему.

Большое спасибо за указание в правильном направлении для решения этой проблемы.

1 Ответ

1 голос
/ 30 апреля 2020

Если я хорошо понимаю, вы хотите изменить backgroundBrush вашего graphicsView, если последний элемент вашего QStringListModel начинается с указанных вами c строк.

Чтобы обнаружить это, вы может подкласс QListView:
listview.h :

#ifndef LISTVIEW_H
#define LISTVIEW_H

#include <QListView>
#include <QStringListModel>

class ListView : public QListView
{
    Q_OBJECT
public:
    ListView(QWidget *parent = nullptr);

signals:
    void changeColor(QColor c);

protected:
    void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>()) override;

};

#endif // LISTVIEW_H

listview. cpp:

#include "listview.h"

ListView::ListView(QWidget *parent)
    : QListView(parent)
{

}

void ListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
    QListView::dataChanged(topLeft, bottomRight, roles);
    /**
     * Assuming that you have just one item changed
     * So topLeft == bottomRight
     */
    if (topLeft.row() == model()->rowCount()-1){
        QString last = topLeft.data().toString();
        if(last.startsWith("[ INFO] Minimum Distance: 5")) {
            emit changeColor(Qt::red);
        } else if(last.startsWith("[ INFO] Minimum Distance: 10")) {
            emit changeColor(Qt::yellow);
        } else if(last.startsWith("[ INFO] Minimum Distance: 15")) {
            emit changeColor(Qt::green);
        }
    }
}

сейчас у вас есть все, что вам нужно, но вам нужно добавить slot, чтобы соединить сигнал вашего пользовательского ListView с вашим QGraphicsView::brush

// Add this in your mainwindows.h
public slots:
    void setGraphicViewColor(QColor c);

// This in the ctor of your MainWindow:
connect(ui->listView, SIGNAL(changeColor(QColor)), this, SLOT(setGraphicViewColor(QColor)));

// And the implementation of your custom slot in mainwindows.cpp
void MainWindow::setGraphicViewColor(QColor c)
{
    qDebug() << "Update your graphicsView backgroundBrush" << c;
    //ui->graphicsView->setBackgroundBrush(c);
}
...