Files
Renderive/Widget/Qt/File_Player_Widget.cpp
T
2026-07-29 12:30:40 +08:00

184 lines
6.0 KiB
C++

#include "File_Player_Widget.h"
#include <string_view>
namespace Psc {
File_Play_Widget::Config::Config() {
log_path = "";
}
Psc::JSON File_Play_Widget::Config::to_json() {
return VAR_JSON_1(log_path);
}
void File_Play_Widget::Config::from_json(Psc::JSON* that_json) {
Get_J(log_path)
}
void File_Play_Widget::save() {
Config config;
config.log_path = path_select->path().toStdString();
save(config);
}
void File_Play_Widget::save(Config& config) {
auto json_file = get_config_path();
std::ofstream ofs(json_file, std::ios::out | std::ios::trunc);
ofs << config.to_json().to_json_string();
ofs.close();
}
File_Play_Widget::File_Play_Widget(std::string_view id) : Base_Cache(id) {
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(4, 4, 4, 4);
layout->setSpacing(6);
path_select = new File_Tool2("回放文件");
layout->addWidget(path_select);
progress_bar = new QProgressBar();
progress_bar->setRange(0, 1000);
progress_bar->setValue(0);
layout->addWidget(progress_bar);
speed_show = new Text_Shower();
speed_show->set_title("回放速度显示");
layout->addWidget(speed_show);
confirm_button = new QPushButton("确定");
layout->addWidget(confirm_button);
QObject::connect(confirm_button, &QPushButton::clicked, [this]() {
if (init) {
Message::show(
Message::warning,
"已经初始化完成过",
this,
3000,
Message::Top_Right);
return;
}
QString qpath = path_select->path();
if (qpath.isEmpty()) {
Message::show(
Message::error,
"路径不能为空",
this,
3000,
Message::Top_Right);
return;
}
std::filesystem::path path = qpath.toStdString();
try {
// 如果是文件路径
std::filesystem::path parent = path.parent_path();
if (!parent.empty() && !std::filesystem::exists(parent)) {
if (!std::filesystem::create_directories(parent)) {
Message::show(
Message::error,
"目录创建失败",
this,
3000,
Message::Top_Right);
return;
}
}
// 如果文件不存在就创建
if (!std::filesystem::exists(path)) {
std::ofstream ofs(path.string(), std::ios::binary);
if (!ofs) {
Message::show(
Message::error,
"文件创建失败",
this,
3000,
Message::Top_Right);
return;
}
}
}
catch (const std::exception& e) {
Message::show(
Message::error,
QString("路径错误: ") + e.what(),
this,
3000,
Message::Top_Right);
return;
}
Message::show(
Message::success,
"初始化成功",
this,
2000,
Message::Top_Right);
// 保存初始化成功的配置文件
save();
});
auto json_file = get_config_path();
Config config;
if (!std::filesystem::exists(json_file)) {
save(config);
}
auto tt = Psc::try_parse_json_file(json_file).and_then([&config](JSON&& json) -> expected<JSON, std::error_code> {
config.from_json(&json);
return {};
});
if (!tt) {
Message::show(
Message::success,
"配置文件加载错误!",
this,
2000,
Message::Top_Right);
}
path_select->set_path(QString::fromStdString(config.log_path));
}
void File_Play_Widget::start(size_t chunk_size, std::chrono::milliseconds interval) {
QString path = path_select->path();
if (path.isEmpty()) {
Message::show(Message::error, QString("路径为空"), this, 3000,
Message::Top_Right);
return;
}
try {
file_player.open(path.toStdString());
}
catch (std::exception& e) {
Message::show(Message::error, QString("文件打开失败: ") + e.what(), this,
3000, Message::Top_Right);
return;
}
speed.clear();
progress_bar->setValue(0);
timer = new QTimer(this);
timer->setInterval(interval.count());
connect(timer, &QTimer::timeout, this, [this, chunk_size]() {
std::vector<std::uint8_t> buffer(chunk_size);
size_t n = file_player.read(buffer.data(), chunk_size);
if (n == 0 || file_player.eof()) {
timer->stop();
file_player.close();
progress_bar->setValue(1000);
return;
}
speed.update(n);
speed_show->set_text(
QString::fromStdString(speed.to_json().to_json_string()));
double p = file_player.progress();
progress_bar->setValue(static_cast<int>(p * 1000));
});
timer->start();
}
Test_File_Play_Widget::Test_File_Play_Widget() {
auto layout = new QVBoxLayout(this);
file_play_widget = new File_Play_Widget("Test_File_Play_Widget");
layout->addWidget(file_play_widget);
layout->addStretch();
interval_select = new Value_Select_Simple<int>();
chunk_select = new Value_Select_Simple<int>();
interval_select->set_value(50);
chunk_select->set_value(4096);
interval_select->set_title("时间间隔(ms)");
chunk_select->set_title("块大小(byte)");
start_button = new QPushButton("开始回放");
layout->addWidget(interval_select);
layout->addWidget(chunk_select);
layout->addWidget(start_button);
connect(start_button, &QPushButton::clicked, this, [this]() {
file_play_widget->speed.clear();
size_t chunk = chunk_select->get_value();
int interval = interval_select->get_value();
file_play_widget->start(chunk, std::chrono::milliseconds(interval));
});
}
} // namespace Psc