В моем сценарии у меня сложная иерархия QObject * и QQuickItem * с множеством дочерних объектов, которые являются критически важными для приложения.
Что я хочу сделать, это:
Выполнить сложную, интенсивную работу с процессором из определенного типа, не зависящего от QObject. Эта операция должна получить доступ к свойствам из множества различных объектов QO в иерархии и потребует копирования и анализа большого объема памяти отдельным потоком (до такой степени, что эффективнее просто блокировать основной цикл событий, чем копировать всеover).
Есть ли способ прямого доступа к объектам QObject, которые являются дочерними по отношению к основному объекту QObject, который создает новый поток?
Позвольте мне пояснить немного с помощью некоторого кода:
Этот фрагмент кода отвечает за поиск соседних блоков в сетке блоков, которые соответствуют определенным условиям (это моя интенсивная работа процессора, потому что она требуетдолжно выполняться много раз за короткий промежуток времени)
QList<QQuickItem *> Blockgrid::find_neighbors(QQuickItem *startItem, QList<QQuickItem *> currentNeighbors, QQuickItem *currentItem)
{
QList<QQuickItem*> neighbors;
QList<QQuickItem*> new_neighbors;
Blockrow* startRow = this->get_item_row(startItem);
int startCell = startRow->get_cell_number(startItem);
int startColor = startItem->property("blockColor").toInt();
Blockrow* currentRow = this->get_item_row(currentItem);
int currentCell = currentRow->get_cell_number(currentItem);
QList<QQuickItem*> potential_neighbors;
QQuickItem* topNeighbor = this->find_block(currentRow->rowNumber() - 1, currentCell);
QQuickItem* bottomNeighbor = this->find_block(currentRow->rowNumber() + 1, currentCell);
QQuickItem* leftNeighbor = this->find_block(currentRow->rowNumber(), currentCell - 1);
QQuickItem* rightNeighbor = this->find_block(currentRow->rowNumber(), currentCell + 1);
if (topNeighbor != nullptr) {
potential_neighbors << topNeighbor;
}
if (bottomNeighbor != nullptr) {
potential_neighbors << bottomNeighbor;
}
if (leftNeighbor != nullptr) {
potential_neighbors << leftNeighbor;
}
if (rightNeighbor != nullptr) {
potential_neighbors << rightNeighbor;
}
foreach (QQuickItem* potentialItem, potential_neighbors) {
if (potentialItem->property("blockColor") == startColor) {
if (potentialItem != currentItem) {
if (!neighbors.contains(potentialItem)) {
new_neighbors << potentialItem;
}
}
}
}
QList<QQuickItem*> final_neighbors;
if (new_neighbors.count() > 0) {
final_neighbors << currentNeighbors;
foreach (QQuickItem* neighborItem, new_neighbors) {
if (!final_neighbors.contains(neighborItem)) {
QList<QQuickItem*> send_neighbors;
send_neighbors << currentNeighbors << neighborItem << this->find_neighbors(startItem, send_neighbors, neighborItem);
foreach (QQuickItem* sendItem, send_neighbors) {
if (!final_neighbors.contains(sendItem)) {
final_neighbors << sendItem;
}
}
}
}
}
return final_neighbors;
}
Важно не код, интенсивно использующий ЦП, который просто служит для обеспечения некоторого контекста сложности операции.
Я пытаюсь выполнить метод detect_matches
в отдельном потоке:
class Worker : public QObject
{
Q_OBJECT
public slots:
void detect_matches(Blockgrid* i_grid)
{
for (int row=0; row<i_grid->numberOfRows; row++) {
for (int col=0; col<i_grid->numberOfRows; col++) {
i_grid->find_block(row, col)->setProperty("opacity", 1.0);
}
}
for (int row=0; row<i_grid->numberOfRows; row++) {
for (int col=0; col<i_grid->numberOfRows; col++) {
QList<QQuickItem*> currentNeighbors;
QList<QQuickItem*> matches;
matches << i_grid->find_neighbors(i_grid->find_block(row, col), currentNeighbors, i_grid->find_block(row, col));
if (matches.count() >= 3) {
foreach (QQuickItem* matchItem, matches) {
matchItem->setProperty("launched", true);
i_grid->find_block(row, col)->setProperty("launched",true);
}
}
}
}
}
}
};
Этот поток запущен с использованием техники moveTothread
:
void Blockgrid::find_matches() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
worker->detect_matches(this);
}
Есть ли способ заставить эту работу? В настоящее время рабочий поток не может взаимодействовать с объектами, которые живут в объекте Blockgrid, после того как он был перемещен в отдельный поток.
Как я уже говорил, копирование всех данных из класса Blockgrid в рабочий потокпо существу потребует больше ресурсов процессора и времени обработки, чем потрачено потоком для завершения вычислений, поэтому я хочу найти метод, который позволит обращаться к объектам через потоки.
Спасибо.