假设我具有类型为 QString 的源数据结构。我的目标是在不同模型( QAbstractTableModel )呈现的不同表( QTableView )中显示此数据。我想在源数据更改时看到这些表中的数据更改,但是没有为每个表模型显式调用 setData (...)。 有可能吗?
------ UPD -------为我的示例添加了代码。我不知道该如何处理。
我不知道如何对不同的表使用相同的模型。 如果您知道,请告诉我如何操作。这是我的测试示例。
#TableTest.pro
QT += widgets
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp
HEADERS += \
main.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
// main.h
#include <QObject>
#include <QTimer>
#include <QString>
#include <QColor>
#include <QTableView>
#include <QHeaderView>
#include <QStandardItemModel>
#include <QStringList>
#define UPDATE_INTERVAL 200
#define MAP_WIDTH 600
#define MAP_HEIGHT 400
#define RAND_HALF (RAND_MAX / 2)
#ifndef MAIN_H
#define MAIN_H
class CTestObject : public QObject
{
Q_OBJECT
public:
CTestObject(QString name, QString user);
void setData(double x, double y, double speed, const QString &zone);
void setData(double speed, double azimuth);
QString Name;
QString User;
double CoordX;
double CoordY;
double Speed;
double Azimuth;
double Weight;
QColor Color;
QString Zone;
signals:
void changed(CTestObject*);
};
//--------------------------------------------- All Objects Table
class CAllObjectsTable : public QStandardItemModel
{
Q_OBJECT
public:
CAllObjectsTable(QString Title, QStringList ColumnHeaders);
void addRecord(CTestObject *object);
void deleteRecord(CTestObject *object);
QTableView *view;
public slots:
virtual void updateRecordData(CTestObject *object);
protected:
QVector<CTestObject*> Objects; // local array pointers to objects (each table has its own set)
};
//--------------------------------------------- Table Zone
class CZoneTable : public CAllObjectsTable
{
Q_OBJECT
public:
CZoneTable(QString Title, QStringList ColumnHeaders) : CAllObjectsTable(Title, ColumnHeaders){}
void addRecord(CTestObject *object);
public slots:
virtual void updateRecordData(CTestObject *object) override;
};
//-------------------------------------------- Users Table
class CUsersTable : public CAllObjectsTable
{
Q_OBJECT
public:
CUsersTable(QString Title, QStringList ColumnHeaders) : CAllObjectsTable(Title, ColumnHeaders){}
void addRecord(CTestObject *object);
public slots:
virtual void updateRecordData(CTestObject *object) override;
};
#endif // MAIN_H
// main.cpp
#include <QApplication>
#include <QtMath>
#include <QDebug>
#include "main.h"
void tmrUpdateEvent();
QVector<CTestObject*> g_Objects; // Global source objects array
CAllObjectsTable *AllObjectsTable;
CZoneTable *ZoneObjectsTable;
CUsersTable *UsersTable;
//-----------------------------------------------------------------
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// create objects
g_Objects.append(new CTestObject("ObjectA", "John"));
g_Objects.append(new CTestObject("ObjectB", "Peter"));
g_Objects.append(new CTestObject("ObjectC", "Mike"));
g_Objects.append(new CTestObject("ObjectD", "Alice"));
g_Objects.append(new CTestObject("ObjectE", "Megan"));
// create tables
AllObjectsTable = new CAllObjectsTable("All Objects", QStringList() << "Object" << "X" << "Y" << "Speed" << "Zone");
for(int c =0; c < g_Objects.size(); c++)
AllObjectsTable->addRecord(g_Objects[c]);
ZoneObjectsTable = new CZoneTable("Zone B1", QStringList() << "Object" << "Weight" << "Speed" << "Azimuth" << "X" << "Y");
UsersTable = new CUsersTable("Users", QStringList() << "User" << "Object" << "Zone" << "X" << "Y");
tmrUpdateEvent();
return app.exec();
}
//------------------------------------------------ Table AllObjects
CAllObjectsTable::CAllObjectsTable(QString Title, QStringList ColumnHeaders)
{
// model
this->setHorizontalHeaderLabels(ColumnHeaders);
// view
view = new QTableView;
view->setWindowTitle(Title);
view->verticalHeader()->hide();
view->setModel(this);
view->show();
}
void CAllObjectsTable::addRecord(CTestObject *object)
{
if(!object)
return;
this->Objects.append(object);
this->insertRow(this->Objects.size() - 1);
this->setData(index((Objects.size() - 1), 0), object->Name, Qt::DisplayRole);
connect(object, SIGNAL(changed(CTestObject*)), this, SLOT(updateRecordData(CTestObject*)));
}
void CAllObjectsTable::deleteRecord(CTestObject *object)
{
for(int c =0; c < this->Objects.size(); c++)
if(this->Objects[c] == object)
{
this->Objects.remove(c);
this->removeRow(c);
}
}
void CAllObjectsTable::updateRecordData(CTestObject *object)
{
for(int c =0; c < this->Objects.size(); c++)
if(this->Objects[c] == object)
{
this->setData(index(c, 1), object->CoordX, Qt::DisplayRole);
this->setData(index(c, 2), object->CoordY, Qt::DisplayRole);
this->setData(index(c, 3), object->Speed, Qt::DisplayRole);
this->setData(index(c, 4), object->Zone, Qt::DisplayRole);
}
}
//------------------------------------------------------- Table Zone
void CZoneTable::addRecord(CTestObject *object)
{
if(!object)
return;
this->Objects.append(object);
this->insertRow(Objects.size() - 1);
this->setData(index((this->Objects.size() - 1), 0), object->Name, Qt::DisplayRole); // Name
this->setData(index((Objects.size() - 1), 1), object->Weight, Qt::DisplayRole); // Weight
connect(object, SIGNAL(changed(CTestObject*)), this, SLOT(updateRecordData(CTestObject*)));
}
void CZoneTable::updateRecordData(CTestObject *object)
{
for(int c =0; c < this->Objects.size(); c++)
if(this->Objects[c] == object)
{
this->setData(index(c, 2), object->Speed, Qt::DisplayRole); // Speed
this->setData(index(c, 3), object->Azimuth, Qt::DisplayRole); // Azimuth
this->setData(index(c, 4), object->CoordX, Qt::DisplayRole); // X
this->setData(index(c, 5), object->CoordY, Qt::DisplayRole); // Y
}
}
//------------------------------------------------------- Table Users
void CUsersTable::addRecord(CTestObject *object)
{
if(!object)
return;
this->Objects.append(object);
this->insertRow(Objects.size() - 1);
this->setData(index((this->Objects.size() - 1), 0), object->User, Qt::DisplayRole); // User
this->setData(index((Objects.size() - 1), 1), object->Name, Qt::DisplayRole); // Name
this->setData(index((Objects.size() - 1), 0), object->Color, Qt::ForegroundRole);
connect(object, SIGNAL(changed(CTestObject*)), this, SLOT(updateRecordData(CTestObject*)));
}
void CUsersTable::updateRecordData(CTestObject *object)
{
for(int c =0; c < this->Objects.size(); c++)
if(this->Objects[c] == object)
{
this->setData(index(c, 2), object->Zone, Qt::DisplayRole); // Zone
this->setData(index(c, 3), object->CoordX, Qt::DisplayRole); // X
this->setData(index(c, 4), object->CoordY, Qt::DisplayRole); // Y
}
}
//------------------------------------------------------- Object
CTestObject::CTestObject(QString name, QString user) : Name(name), User(user)
{
Weight =(std::rand() % 20000);
Color =(std::rand() << 15 | std::rand());
setData((std::rand() % MAP_WIDTH), (std::rand() % MAP_HEIGHT), 0, "");
setData(std::rand(), ((double)(std::rand() - RAND_HALF) / RAND_MAX));
}
void CTestObject::setData(double x, double y, double speed, const QString &zone)
{
this->CoordX =x;
this->CoordY =y;
this->Speed =speed;
this->Zone =zone;
emit changed(this);
}
void CTestObject::setData(double speed, double azimuth)
{
this->Speed =std::fmod(speed, 1000);
this->Azimuth =azimuth;
emit changed(this);
}
//----------------------------------------------------------
QString GetZoneXY(double x, double y)
{
double ZoneWidth =(MAP_WIDTH / 3), ZoneHeight =(MAP_HEIGHT / 3);
QString Zone ="";
if(x < ZoneWidth)
Zone +="A";
else
if(x < (ZoneWidth * 2))
Zone +="B";
else
Zone +="C";
if(y < ZoneHeight)
Zone +="0";
else
if(y < (ZoneHeight * 2))
Zone +="1";
else
Zone +="2";
return(Zone);
}
//============================================== Update =================================
void tmrUpdateEvent()
{
for(int c =0; c < g_Objects.size(); c++)
{
double s;
s =(g_Objects[c]->Speed - (0.001 * g_Objects[c]->Weight));
if(s > 10) // if Object moving - update Coords & Speed
{
double x =g_Objects[c]->CoordX, y =g_Objects[c]->CoordY, a =g_Objects[c]->Azimuth;
QString z;
x =std::fmod(x + (std::sin(a) * s * 0.01), MAP_WIDTH);
y =std::fmod(y + (std::cos(a) * s * 0.01), MAP_HEIGHT);
while(x < 0)
x +=MAP_WIDTH;
while(y < 0)
y +=MAP_HEIGHT;
z =GetZoneXY(x, y); // current zone
// check objects for Zone table
if(g_Objects[c]->Zone == "B1" && z != "B1")
ZoneObjectsTable->deleteRecord(g_Objects[c]);
else
if(z == "B1" && g_Objects[c]->Zone != "B1")
ZoneObjectsTable->addRecord(g_Objects[c]);
// check objects for Users table
if(z != "B1" && g_Objects[c]->Zone == "B1")
UsersTable->addRecord(g_Objects[c]);
else
if(z == "B1" && g_Objects[c]->Zone != "B1")
UsersTable->deleteRecord(g_Objects[c]);
g_Objects[c]->setData(x, y, s, z);
}
else // new Speed & Direction
g_Objects[c]->setData(std::rand(), ((double)(std::rand() - RAND_HALF) / RAND_MAX));
}
QTimer::singleShot(UPDATE_INTERVAL, [=](){tmrUpdateEvent();});
}
答案 0 :(得分:0)
谢谢大家。我找到了问题的答案-不,这是不可能的。 问题是setData(...)通过复制为模型设置数据。而且我想插入到它们的链接,而不是稍后再捕获有关数据更改的信号。像这样的东西。