171 lines
5.8 KiB
Markdown
171 lines
5.8 KiB
Markdown
# Асинхронный парсинг файлов
|
||
|
||
## Обзор
|
||
Добавлена поддержка асинхронного парсинга файлов через `QFuture` и `QtConcurrent`, что позволяет не блокировать GUI во время обработки больших файлов.
|
||
|
||
## Преимущества асинхронного парсинга
|
||
|
||
### ✅ Не блокирует GUI
|
||
- Интерфейс остается отзывчивым во время парсинга
|
||
- Пользователь может продолжать работу с приложением
|
||
- Прогресс-бар показывает ход выполнения
|
||
|
||
### ✅ Отмена парсинга
|
||
- Возможность отменить парсинг в любой момент
|
||
- Освобождение ресурсов при отмене
|
||
- Безопасное завершение операций
|
||
|
||
### ✅ Обработка больших файлов
|
||
- Эффективная обработка файлов любого размера
|
||
- Не зависает при парсинге сложных проектов
|
||
- Прогрессивная загрузка данных
|
||
|
||
## Реализация
|
||
|
||
### AltiumParser
|
||
**Файл:** `controller/altiumparser.h`
|
||
|
||
**Добавленные методы:**
|
||
```cpp
|
||
// Асинхронный парсинг
|
||
bool parseFileAsync(const QString &filename, ComponentModel *model);
|
||
bool isParsingAsync() const;
|
||
void cancelParsing();
|
||
```
|
||
|
||
**Приватные члены:**
|
||
```cpp
|
||
QFutureWatcher<bool> *m_parseWatcher;
|
||
bool m_isParsingAsync;
|
||
```
|
||
|
||
### MainController
|
||
**Файл:** `controller/maincontroller.h`
|
||
|
||
**Добавленные методы:**
|
||
```cpp
|
||
bool parseFileAsync(const QString &filePath);
|
||
bool isParsingAsync() const;
|
||
void cancelParsing();
|
||
```
|
||
|
||
## Использование
|
||
|
||
### Синхронный парсинг (блокирует GUI)
|
||
```cpp
|
||
bool success = controller.parseFile("project.PrjPcb");
|
||
if (success) {
|
||
qDebug() << "Парсинг завершен";
|
||
}
|
||
```
|
||
|
||
### Асинхронный парсинг (не блокирует GUI)
|
||
```cpp
|
||
// Подключаем сигналы
|
||
connect(&controller, &MainController::parsingProgress,
|
||
[](int progress) { qDebug() << "Прогресс:" << progress << "%"; });
|
||
|
||
connect(&controller, &MainController::parsingFinished,
|
||
[](bool success) { qDebug() << "Завершено:" << success; });
|
||
|
||
// Запускаем асинхронный парсинг
|
||
bool started = controller.parseFileAsync("project.PrjPcb");
|
||
|
||
// Проверяем статус
|
||
if (controller.isParsingAsync()) {
|
||
qDebug() << "Парсинг выполняется...";
|
||
}
|
||
|
||
// При необходимости отменяем
|
||
controller.cancelParsing();
|
||
```
|
||
|
||
## Сигналы и слоты
|
||
|
||
### Сигналы парсера:
|
||
- `parsingProgress(int percentage)` - прогресс парсинга
|
||
- `parsingFinished(bool success)` - завершение парсинга
|
||
- `parsingError(const QString &error)` - ошибка парсинга
|
||
|
||
### Обработка в GUI:
|
||
```cpp
|
||
// В MainWindow или другом виджете
|
||
connect(m_controller, &MainController::parsingProgress,
|
||
this, &MainWindow::updateProgressBar);
|
||
|
||
connect(m_controller, &MainController::parsingFinished,
|
||
this, &MainWindow::onParsingFinished);
|
||
|
||
connect(m_controller, &MainController::parsingError,
|
||
this, &MainWindow::showError);
|
||
```
|
||
|
||
## Рекомендации
|
||
|
||
### Когда использовать асинхронный парсинг:
|
||
1. **Большие файлы** - проекты с множеством компонентов
|
||
2. **Сложные проекты** - с множественными вариантами
|
||
3. **Интерактивные приложения** - где важна отзывчивость GUI
|
||
4. **Длительные операции** - парсинг занимает более 1-2 секунд
|
||
|
||
### Когда использовать синхронный парсинг:
|
||
1. **Маленькие файлы** - простые проекты
|
||
2. **Тестирование** - для отладки и тестов
|
||
3. **Простые операции** - где блокировка GUI не критична
|
||
|
||
## Пример интеграции
|
||
|
||
```cpp
|
||
class ProjectManager : public QObject
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
void parseProject(const QString &filePath) {
|
||
if (m_controller.isParsingAsync()) {
|
||
qDebug() << "Парсинг уже выполняется";
|
||
return;
|
||
}
|
||
|
||
// Запускаем асинхронный парсинг
|
||
m_controller.parseFileAsync(filePath);
|
||
}
|
||
|
||
void cancelParsing() {
|
||
m_controller.cancelParsing();
|
||
}
|
||
|
||
private slots:
|
||
void onParsingProgress(int progress) {
|
||
// Обновляем прогресс-бар
|
||
m_progressBar->setValue(progress);
|
||
}
|
||
|
||
void onParsingFinished(bool success) {
|
||
if (success) {
|
||
// Загружаем данные из БД
|
||
m_controller.loadComponentsFromDatabase();
|
||
m_controller.loadProjectParamsFromDatabase();
|
||
|
||
// Обновляем интерфейс
|
||
updateView();
|
||
} else {
|
||
// Показываем ошибку
|
||
showError("Ошибка парсинга");
|
||
}
|
||
}
|
||
|
||
private:
|
||
MainController m_controller;
|
||
QProgressBar *m_progressBar;
|
||
};
|
||
```
|
||
|
||
## Заключение
|
||
|
||
Асинхронный парсинг обеспечивает:
|
||
- ✅ Отзывчивый интерфейс
|
||
- ✅ Возможность отмены операций
|
||
- ✅ Эффективную обработку больших файлов
|
||
- ✅ Прогрессивную загрузку данных
|
||
- ✅ Безопасное завершение операций |