feat: 添加状态栏显示模型名称和加载状态
主窗口底部状态栏实时显示模型加载状态: - 已就绪:绿色显示"模型已就绪: <文件名>" - 路径为空:红色显示"⚠️ 模型路径未设置" - 加载失败:橙色显示"⚠️ 模型加载失败: <文件名>" Application 新增 modelLoading 信号和 modelPath() 方法, 配置变化时自动刷新状态栏显示。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ef97b962c3
commit
6f55ec5780
@ -20,8 +20,9 @@ Application::Application(int& argc, char** argv)
|
|||||||
sttEngine_ = new SenseVoiceEngine(this);
|
sttEngine_ = new SenseVoiceEngine(this);
|
||||||
connect(sttEngine_, &SenseVoiceEngine::modelLoaded, this, [this](const QString& path) {
|
connect(sttEngine_, &SenseVoiceEngine::modelLoaded, this, [this](const QString& path) {
|
||||||
modelLoaded_ = true;
|
modelLoaded_ = true;
|
||||||
|
modelPath_ = path;
|
||||||
LOG_INFO(kTag, QString("全局模型已加载: %1").arg(path));
|
LOG_INFO(kTag, QString("全局模型已加载: %1").arg(path));
|
||||||
emit modelLoaded();
|
emit modelLoaded(path);
|
||||||
});
|
});
|
||||||
connect(sttEngine_, &SenseVoiceEngine::modelLoadError, this, [this](const QString&, const QString& err) {
|
connect(sttEngine_, &SenseVoiceEngine::modelLoadError, this, [this](const QString&, const QString& err) {
|
||||||
modelLoaded_ = false;
|
modelLoaded_ = false;
|
||||||
@ -54,9 +55,12 @@ void Application::loadGlobalModel() {
|
|||||||
QString modelPath = configManager_->get("stt.model_path").toString();
|
QString modelPath = configManager_->get("stt.model_path").toString();
|
||||||
if (modelPath.isEmpty()) {
|
if (modelPath.isEmpty()) {
|
||||||
LOG_WARNING(kTag, "模型路径为空,请在配置中设置后重启");
|
LOG_WARNING(kTag, "模型路径为空,请在配置中设置后重启");
|
||||||
|
emit modelLoadError("模型路径未设置");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modelPath_ = modelPath;
|
||||||
|
|
||||||
QString tokensPath = configManager_->get("stt.tokens_path").toString();
|
QString tokensPath = configManager_->get("stt.tokens_path").toString();
|
||||||
QString device = configManager_->get("stt.device").toString();
|
QString device = configManager_->get("stt.device").toString();
|
||||||
int numThreads = configManager_->get("stt.num_threads").toInt();
|
int numThreads = configManager_->get("stt.num_threads").toInt();
|
||||||
@ -65,6 +69,7 @@ void Application::loadGlobalModel() {
|
|||||||
sttEngine_->setDebugSaveAudio(debugSave);
|
sttEngine_->setDebugSaveAudio(debugSave);
|
||||||
|
|
||||||
LOG_INFO(kTag, QString("正在异步加载全局模型: %1").arg(modelPath));
|
LOG_INFO(kTag, QString("正在异步加载全局模型: %1").arg(modelPath));
|
||||||
|
emit modelLoading(modelPath);
|
||||||
sttEngine_->loadModelAsync(modelPath, tokensPath, device, numThreads);
|
sttEngine_->loadModelAsync(modelPath, tokensPath, device, numThreads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,12 +26,18 @@ public:
|
|||||||
/** @brief 获取全局 STT 引擎(共享实例) */
|
/** @brief 获取全局 STT 引擎(共享实例) */
|
||||||
SenseVoiceEngine* sttEngine() const;
|
SenseVoiceEngine* sttEngine() const;
|
||||||
|
|
||||||
|
/** @brief 获取当前模型路径 */
|
||||||
|
QString modelPath() const { return modelPath_; }
|
||||||
|
|
||||||
/** @brief 获取全局 STT 引擎加载状态 */
|
/** @brief 获取全局 STT 引擎加载状态 */
|
||||||
bool isModelLoaded() const;
|
bool isModelLoaded() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/** @brief 模型加载完成 */
|
/** @brief 模型加载中(带路径) */
|
||||||
void modelLoaded();
|
void modelLoading(const QString& modelPath);
|
||||||
|
|
||||||
|
/** @brief 模型加载完成(带路径) */
|
||||||
|
void modelLoaded(const QString& modelPath);
|
||||||
|
|
||||||
/** @brief 模型加载失败 */
|
/** @brief 模型加载失败 */
|
||||||
void modelLoadError(const QString& error);
|
void modelLoadError(const QString& error);
|
||||||
@ -41,6 +47,7 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<ConfigManager> configManager_;
|
std::unique_ptr<ConfigManager> configManager_;
|
||||||
SenseVoiceEngine* sttEngine_ = nullptr;
|
SenseVoiceEngine* sttEngine_ = nullptr;
|
||||||
|
QString modelPath_;
|
||||||
bool modelLoaded_ = false;
|
bool modelLoaded_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,9 @@
|
|||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
static const char* const kTag = "MainWindow";
|
static const char* const kTag = "MainWindow";
|
||||||
|
|
||||||
@ -28,6 +31,7 @@ MainWindow::MainWindow(ConfigManager* configManager,
|
|||||||
|
|
||||||
setupUI(sttEngine);
|
setupUI(sttEngine);
|
||||||
setupMenuBar();
|
setupMenuBar();
|
||||||
|
setupStatusBar(sttEngine);
|
||||||
loadStyleSheet();
|
loadStyleSheet();
|
||||||
|
|
||||||
// 初始化语音输入服务(共享全局引擎)
|
// 初始化语音输入服务(共享全局引擎)
|
||||||
@ -71,6 +75,29 @@ void MainWindow::setupUI(SenseVoiceEngine* sttEngine) {
|
|||||||
setCentralWidget(tabWidget_);
|
setCentralWidget(tabWidget_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupStatusBar(SenseVoiceEngine* sttEngine) {
|
||||||
|
sttEngine_ = sttEngine;
|
||||||
|
|
||||||
|
auto* bar = statusBar();
|
||||||
|
bar->setSizeGripEnabled(false);
|
||||||
|
|
||||||
|
modelStatusLabel_ = new QLabel(this);
|
||||||
|
modelStatusLabel_->setStyleSheet(
|
||||||
|
"QLabel { padding: 2px 8px; font-size: 13px; }");
|
||||||
|
bar->addPermanentWidget(modelStatusLabel_);
|
||||||
|
|
||||||
|
// 连接全局引擎信号
|
||||||
|
connect(sttEngine_, &SenseVoiceEngine::modelLoaded,
|
||||||
|
this, &MainWindow::updateModelStatus);
|
||||||
|
connect(sttEngine_, &SenseVoiceEngine::modelLoadError,
|
||||||
|
this, &MainWindow::updateModelStatus);
|
||||||
|
connect(sttEngine_, &SenseVoiceEngine::modelUnloaded,
|
||||||
|
this, &MainWindow::updateModelStatus);
|
||||||
|
|
||||||
|
// 初始化显示
|
||||||
|
updateModelStatus();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::setupMenuBar() {
|
void MainWindow::setupMenuBar() {
|
||||||
// 文件菜单
|
// 文件菜单
|
||||||
auto* fileMenu = menuBar()->addMenu("文件");
|
auto* fileMenu = menuBar()->addMenu("文件");
|
||||||
@ -112,9 +139,35 @@ void MainWindow::closeEvent(QCloseEvent* event) {
|
|||||||
QMainWindow::closeEvent(event);
|
QMainWindow::closeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateModelStatus() {
|
||||||
|
if (!sttEngine_ || !modelStatusLabel_) return;
|
||||||
|
|
||||||
|
QString modelPath = configManager_->get("stt.model_path").toString();
|
||||||
|
QString modelName = modelPath.isEmpty() ? QString() : QFileInfo(modelPath).fileName();
|
||||||
|
|
||||||
|
if (sttEngine_->isLoaded()) {
|
||||||
|
QString statusText = modelName.isEmpty() ? "模型已就绪" : QString("模型已就绪: %1").arg(modelName);
|
||||||
|
modelStatusLabel_->setText(statusText);
|
||||||
|
modelStatusLabel_->setStyleSheet(
|
||||||
|
"QLabel { padding: 2px 8px; font-size: 13px; color: #27ae60; font-weight: bold; }");
|
||||||
|
} else if (modelPath.isEmpty()) {
|
||||||
|
modelStatusLabel_->setText("⚠️ 模型路径未设置");
|
||||||
|
modelStatusLabel_->setStyleSheet(
|
||||||
|
"QLabel { padding: 2px 8px; font-size: 13px; color: #e74c3c; }");
|
||||||
|
} else {
|
||||||
|
modelStatusLabel_->setText(
|
||||||
|
QString("⚠️ 模型加载失败: %1").arg(modelName));
|
||||||
|
modelStatusLabel_->setStyleSheet(
|
||||||
|
"QLabel { padding: 2px 8px; font-size: 13px; color: #e67e22; }");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::onVoiceInputConfigChanged() {
|
void MainWindow::onVoiceInputConfigChanged() {
|
||||||
if (!voiceInputService_) return;
|
if (!voiceInputService_) return;
|
||||||
|
|
||||||
|
// 更新模型状态显示
|
||||||
|
updateModelStatus();
|
||||||
|
|
||||||
bool enabled = configManager_->get("stt.capslock_voice_enabled").toBool();
|
bool enabled = configManager_->get("stt.capslock_voice_enabled").toBool();
|
||||||
if (enabled && !voiceInputService_->isRunning()) {
|
if (enabled && !voiceInputService_->isRunning()) {
|
||||||
voiceInputService_->start();
|
voiceInputService_->start();
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
namespace impress {
|
namespace impress {
|
||||||
|
|
||||||
class ConfigManager;
|
class ConfigManager;
|
||||||
@ -17,6 +19,7 @@ class VoiceInputService;
|
|||||||
* @brief 主窗口
|
* @brief 主窗口
|
||||||
*
|
*
|
||||||
* 使用 Tab 页导航管理三个功能页面,共享全局 STT 引擎。
|
* 使用 Tab 页导航管理三个功能页面,共享全局 STT 引擎。
|
||||||
|
* 状态栏显示模型名称和加载状态。
|
||||||
*/
|
*/
|
||||||
class MainWindow : public QMainWindow {
|
class MainWindow : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -32,15 +35,19 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void setupUI(SenseVoiceEngine* sttEngine);
|
void setupUI(SenseVoiceEngine* sttEngine);
|
||||||
void setupMenuBar();
|
void setupMenuBar();
|
||||||
|
void setupStatusBar(SenseVoiceEngine* sttEngine);
|
||||||
void loadStyleSheet();
|
void loadStyleSheet();
|
||||||
void onVoiceInputConfigChanged();
|
void onVoiceInputConfigChanged();
|
||||||
|
void updateModelStatus();
|
||||||
|
|
||||||
ConfigManager* configManager_;
|
ConfigManager* configManager_;
|
||||||
|
SenseVoiceEngine* sttEngine_;
|
||||||
VoiceInputService* voiceInputService_;
|
VoiceInputService* voiceInputService_;
|
||||||
STTTestPage* sttPage_;
|
STTTestPage* sttPage_;
|
||||||
FileTranscribePage* transcribePage_;
|
FileTranscribePage* transcribePage_;
|
||||||
SettingsPage* settingsPage_;
|
SettingsPage* settingsPage_;
|
||||||
QTabWidget* tabWidget_;
|
QTabWidget* tabWidget_;
|
||||||
|
QLabel* modelStatusLabel_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace impress
|
} // namespace impress
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user