add,计划采集17:

1、2轴控制:采集完成后回到原点;
2、将拉伸放入单独线程,防止主界面卡顿;
3、美化定时采集窗口;
4、优化taskExecutor;
This commit is contained in:
tangchao0503
2026-06-30 09:52:52 +08:00
parent 55609b7b3b
commit 7167c5adce
8 changed files with 525 additions and 92 deletions

View File

@ -97,6 +97,11 @@ void TwoMotionCaptureCoordinator::getLocBeforeStart()
loop.exec(); loop.exec();
std::vector<double> pos;
pos.push_back(0);
pos.push_back(0);
m_locBeforeStart = pos;
disconnect(conn); disconnect(conn);
} }

View File

@ -553,6 +553,20 @@ HPPA::HPPA(QWidget* parent)
} }
)"); )");
m_ImageStretchThread = new QThread(this);
m_ImageStretchWorker = new ImageStretchWorker();
m_ImageStretchWorker->moveToThread(m_ImageStretchThread);
// 注册QPixmap类型用于跨线程信号槽
qRegisterMetaType<QPixmap>("QPixmap&");
qRegisterMetaType<cv::Mat>("cv::Mat");
qRegisterMetaType<cv::Mat>("cv::Mat");
connect(m_ImageStretchWorker, &ImageStretchWorker::imageReady,
this, &HPPA::onStretchedImageReady, Qt::QueuedConnection);
connect(m_ImageStretchWorker, &ImageStretchWorker::processingError,
this, &HPPA::onStretchProcessingError, Qt::QueuedConnection);
m_ImageStretchThread->start();
//光谱仪操作 //光谱仪操作
m_Imager = nullptr; m_Imager = nullptr;
m_RecordThread = nullptr; m_RecordThread = nullptr;
@ -1182,6 +1196,14 @@ HPPA::~HPPA()
{ {
s_instance = nullptr; s_instance = nullptr;
} }
m_ImageStretchThread->quit();
m_ImageStretchThread->wait(3000);
delete m_ImageStretchWorker;
m_ImageStretchWorker = nullptr;
delete m_ImageStretchThread;
m_ImageStretchThread = nullptr;
} }
void HPPA::removeLayerByTreeIndex() void HPPA::removeLayerByTreeIndex()
@ -2626,14 +2648,20 @@ void HPPA::onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QSt
QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>(); QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>();
currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFrameCounter());//界面中显示已经采集的帧数 currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFrameCounter());//界面中显示已经采集的帧数
//创建需要显示的图像--opencv版本
ImageProcessor imageProcessor;
//cv::Mat rgbImage(*m_Imager->getRgbImage()->m_matRgbImage, cv::Range(0, m_Imager->getFrameCounter()), cv::Range::all());//2022.3.18重构的
cv::Mat rgbImage(*m_Imager->getMatRgbImage(), cv::Range(0, m_Imager->getFrameCounter()), cv::Range::all()); cv::Mat rgbImage(*m_Imager->getMatRgbImage(), cv::Range(0, m_Imager->getFrameCounter()), cv::Range::all());
cv::Mat rgbImageStretched = imageProcessor.CStretch(rgbImage, 0.02); showQuickPreview(fileNumber, filePath, rgbImage);
//在界面中显示图像
currentImageViewer[0]->SetImage(&QPixmap::fromImage(imageProcessor.Mat2QImage(rgbImageStretched)));//绘制图像 if (m_ImageStretchWorker) {
// 深拷贝图像数据,因为原始数据可能在处理完成前被修改
cv::Mat rgbImageCopy = rgbImage.clone();
QMetaObject::invokeMethod(m_ImageStretchWorker, "processImage",
Qt::QueuedConnection,
Q_ARG(cv::Mat, rgbImageCopy),
Q_ARG(int, fileNumber),
Q_ARG(QString, filePath),
Q_ARG(float, 0.02f));
}
//20241225 //20241225
//保存拉伸后的rgb //保存拉伸后的rgb
@ -2652,6 +2680,43 @@ void HPPA::onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QSt
//currentImageViewer[0]->SetImage(&QPixmap::fromImage(CuttedImage));//绘制图像 //currentImageViewer[0]->SetImage(&QPixmap::fromImage(CuttedImage));//绘制图像
} }
void HPPA::showQuickPreview(int fileNumber, const QString& filePath, const cv::Mat& rgbImage)
{
// 可以显示一个简单缩放的预览图,或者显示"处理中..."的提示
// 这里简单地跳过,等待拉伸后的图像
// 如果需要快速预览,可以进行简单的缩放显示
/*
QWidget* currentWidget = m_MapLayerStore->widgetForLayer(filePath);
if (!currentWidget) return;
QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>();
if (currentImageViewer.isEmpty()) return;
// 显示一个简单的灰度或缩放版本作为预览
cv::Mat preview;
cv::resize(rgbImage, preview, cv::Size(), 0.25, 0.25); // 缩小到25%
// ... 转换并显示
*/
}
void HPPA::onStretchedImageReady(int fileNumber, const QString& filePath, QPixmap& pixmap)
{
QWidget* currentWidget = m_MapLayerStore->widgetForLayer(filePath);
if (!currentWidget) return;
QList<Mapcavas*> currentImageViewer = currentWidget->findChildren<Mapcavas*>();
if (currentImageViewer.isEmpty()) return;
// 在界面中显示拉伸后的图像
currentImageViewer[0]->SetImage(&pixmap);
}
// 处理错误的回调
void HPPA::onStretchProcessingError(int fileNumber, const QString& filePath, const QString& error)
{
qDebug() << "Image stretch error for file" << filePath << ":" << error;
// 可以选择显示错误信息或保留之前的图像
}
void HPPA::focusPlotSpectralImg(int state) void HPPA::focusPlotSpectralImg(int state)
{ {
if (!m_Imager) return; if (!m_Imager) return;
@ -2966,3 +3031,185 @@ void HPPA::onBandSelectionChanged(double rWave, double gWave, double bWave)
mapcavas[0]->freshmap(); mapcavas[0]->freshmap();
} }
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ImageStretchWorker::ImageStretchWorker(QObject* parent)
: QObject(parent)
{
}
ImageStretchWorker::~ImageStretchWorker()
{
}
void ImageStretchWorker::processImage(const cv::Mat& rgbImage, int fileNumber, const QString& filePath, float ratio)
{
try {
if (rgbImage.empty()) {
emit processingError(fileNumber, filePath, "Empty image");
return;
}
// 执行耗时的拉伸操作
cv::Mat rgbImageStretched = CStretch(rgbImage, ratio);
// 转换为QImage再转为QPixmap
QImage qimg = Mat2QImage(rgbImageStretched);
QPixmap pixmap = QPixmap::fromImage(qimg);
emit imageReady(fileNumber, filePath, pixmap);
}
catch (const std::exception& e) {
emit processingError(fileNumber, filePath, QString::fromStdString(e.what()));
}
}
std::vector<cv::Point2f> ImageStretchWorker::CHistogram(const cv::Mat& img)
{
cv::Mat mimg = img.clone();
int rows = mimg.rows;
int cols = mimg.cols;
int maxValue = 65535;
std::vector<long int> hisnum(maxValue, 0);
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
unsigned short gv = mimg.at<unsigned short>(i, j);
if (gv >= maxValue)
{
++hisnum[0];
}
else
{
++hisnum[gv];
}
}
}
long int pnum = rows * cols;
std::vector<cv::Point2f> hisp;
hisp.reserve(hisnum.size());
for (size_t i = 0; i < hisnum.size(); ++i)
{
float p = static_cast<float>(hisnum[i]) / pnum;
hisp.push_back(cv::Point2f(static_cast<float>(i), p));
}
return hisp;
}
uint ImageStretchWorker::MaxRatio(const std::vector<cv::Point2f>& data, float ratio)
{
float maxp = 0;
uint outnum = 0;
for (int i = static_cast<int>(data.size()) - 1; i >= 0; --i)
{
maxp += data[i].y;
if (maxp >= ratio)
{
outnum = i;
break;
}
}
return outnum;
}
uint ImageStretchWorker::MinRatio(const std::vector<cv::Point2f>& data, float ratio)
{
float minp = 0;
uint outnum = 0;
for (size_t i = 0; i < data.size(); ++i)
{
minp += data[i].y;
if (minp >= ratio)
{
outnum = static_cast<uint>(i);
break;
}
}
return outnum;
}
cv::Mat ImageStretchWorker::CStretchDeal(const cv::Mat& img, uint minnum, uint maxnum)
{
cv::Mat mimg = img.clone();
int rows = mimg.rows;
int cols = mimg.cols;
cv::Mat nimg = cv::Mat::zeros(rows, cols, CV_8U);
float dertnum = static_cast<float>(maxnum - minnum);
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
unsigned short a = mimg.at<unsigned short>(i, j);
if (a <= minnum)
nimg.at<uchar>(i, j) = 0;
else if (a >= maxnum)
nimg.at<uchar>(i, j) = 255;
else
nimg.at<uchar>(i, j) = static_cast<uchar>(255 * (a - minnum) / dertnum);
}
}
return nimg;
}
cv::Mat ImageStretchWorker::CStretch(const cv::Mat& img, float ratio)
{
cv::Mat mimg = img.clone();
cv::Mat bgr[3];
cv::split(mimg, bgr);
std::vector<cv::Point2f> hb = CHistogram(bgr[0]);
std::vector<cv::Point2f> hg = CHistogram(bgr[1]);
std::vector<cv::Point2f> hr = CHistogram(bgr[2]);
uint minb = MinRatio(hb, ratio);
uint ming = MinRatio(hg, ratio);
uint minr = MinRatio(hr, ratio);
uint maxb = MaxRatio(hb, ratio);
uint maxg = MaxRatio(hg, ratio);
uint maxr = MaxRatio(hr, ratio);
cv::Mat b = CStretchDeal(bgr[0], minb, maxb);
cv::Mat g = CStretchDeal(bgr[1], ming, maxg);
cv::Mat r = CStretchDeal(bgr[2], minr, maxr);
cv::Mat newbgr;
newbgr.create(img.rows, img.cols, CV_32FC3);
cv::Mat nbgr[3] = { b, g, r };
cv::merge(nbgr, 3, newbgr);
return newbgr;
}
QImage ImageStretchWorker::Mat2QImage(const cv::Mat& cvImg)
{
QImage qImg;
if (cvImg.channels() == 3)
{
cv::Mat rgbImg;
cv::cvtColor(cvImg, rgbImg, cv::COLOR_BGR2RGB);
qImg = QImage(rgbImg.data,
rgbImg.cols, rgbImg.rows,
static_cast<int>(rgbImg.step),
QImage::Format_RGB888).copy(); // 使用copy()确保数据独立
}
else if (cvImg.channels() == 1)
{
qImg = QImage(cvImg.data,
cvImg.cols, cvImg.rows,
static_cast<int>(cvImg.step),
QImage::Format_Indexed8).copy();
}
else
{
qImg = QImage(cvImg.data,
cvImg.cols, cvImg.rows,
static_cast<int>(cvImg.step),
QImage::Format_RGB888).copy();
}
return qImg;
}

View File

@ -88,6 +88,8 @@
#include "PowerControl3D.h" #include "PowerControl3D.h"
#include <algorithm>
#define PI 3.1415926 #define PI 3.1415926
QT_CHARTS_USE_NAMESPACE//QChartView 使用 需要加宏, 否则无法使用 QT_CHARTS_USE_NAMESPACE//QChartView 使用 需要加宏, 否则无法使用
@ -194,6 +196,26 @@ private:
QPixmap m_pixmap; QPixmap m_pixmap;
}; };
class ImageStretchWorker : public QObject
{
Q_OBJECT
public:
explicit ImageStretchWorker(QObject* parent = nullptr);
~ImageStretchWorker();
public slots:
void processImage(const cv::Mat& rgbImage, int fileNumber, const QString& filePath, float ratio = 0.02f);
signals:
void imageReady(int fileNumber, const QString& filePath, QPixmap& pixmap);
void processingError(int fileNumber, const QString& filePath, const QString& error);
private:
cv::Mat CStretch(const cv::Mat& img, float ratio);
cv::Mat CStretchDeal(const cv::Mat& img, uint minnum, uint maxnum);
std::vector<cv::Point2f> CHistogram(const cv::Mat& img);
uint MaxRatio(const std::vector<cv::Point2f>& data, float ratio);
uint MinRatio(const std::vector<cv::Point2f>& data, float ratio);
QImage Mat2QImage(const cv::Mat& cvImg);
};
class HPPA : public QMainWindow class HPPA : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
@ -325,6 +347,13 @@ private:
void initTimedDataCollection(); void initTimedDataCollection();
QThread* m_ImageStretchThread = nullptr;
ImageStretchWorker* m_ImageStretchWorker = nullptr;
// 用于临时显示的未拉伸图像(可选,用于快速预览)
void showQuickPreview(int fileNumber, const QString& filePath, const cv::Mat& rgbImage);
public Q_SLOTS: public Q_SLOTS:
void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath); void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath);
void focusPlotSpectralImg(int state); void focusPlotSpectralImg(int state);
@ -408,6 +437,10 @@ public Q_SLOTS:
void setTimedDataCollectionCamParm(int camType, int captureIntervalSeconds, QString folder); void setTimedDataCollectionCamParm(int camType, int captureIntervalSeconds, QString folder);
void setTimedDataCollectionMotorParm(QString pathLineFilePath); void setTimedDataCollectionMotorParm(QString pathLineFilePath);
void onStartTimedDataCollection(int camType); void onStartTimedDataCollection(int camType);
void onStretchedImageReady(int fileNumber, const QString& filePath, QPixmap& pixmap);
void onStretchProcessingError(int fileNumber, const QString& filePath, const QString& error);
protected: protected:
void closeEvent(QCloseEvent* event) override; void closeEvent(QCloseEvent* event) override;

View File

@ -212,13 +212,16 @@ QVariant TaskTreeModel::data(const QModelIndex& index, int role) const
TaskStatus status = TaskStatus::Waiting; TaskStatus status = TaskStatus::Waiting;
if (node->nodeType == TreeNodeType::Task && node->taskData) { if (node->nodeType == TreeNodeType::Task && node->taskData) {
status = node->taskData->status; status = node->taskData->status;
return QBrush(QColor("#E2EDFF")); // 深绿色文字
} }
else if (node->nodeType == TreeNodeType::SubTask && node->subTaskData) { else if (node->nodeType == TreeNodeType::SubTask && node->subTaskData) {
status = node->subTaskData->status; status = node->subTaskData->status;
return QBrush(QColor("#E2EDFF")); // 深绿色文字
} }
if (status == TaskStatus::Running) { if (status == TaskStatus::Running) {
return QBrush(QColor(0, 100, 0)); // 深绿色文字 return QBrush(QColor("#E2EDFF")); // 深绿色文字
} }
return QBrush(QColor("#E2EDFF")); // 深绿色文字
} }
else if (role == Qt::FontRole) { else if (role == Qt::FontRole) {
QFont font; QFont font;
@ -615,12 +618,12 @@ QString TaskTreeModel::formatDuration(double minutes) const
QColor TaskTreeModel::statusColor(TaskStatus status) const QColor TaskTreeModel::statusColor(TaskStatus status) const
{ {
switch (status) { switch (status) {
case TaskStatus::Waiting: return QColor(255, 255, 230); // 浅黄 case TaskStatus::Waiting: return QColor("#121945"); // 浅黄
case TaskStatus::Running: return QColor(200, 255, 200); // 浅绿 case TaskStatus::Running: return QColor("#121945"); // 浅绿
case TaskStatus::Finished: return QColor(220, 220, 255); // 浅蓝 case TaskStatus::Finished: return QColor("#121945"); // 浅蓝
case TaskStatus::Skiped: return QColor(220, 220, 220); // 浅灰 case TaskStatus::Skiped: return QColor("#121945"); // 浅灰
} }
return QColor(255, 255, 255); return QColor("#121945");
} }
QString TaskTreeModel::formatCountdown(qint64 seconds) const QString TaskTreeModel::formatCountdown(qint64 seconds) const

View File

@ -77,8 +77,8 @@ void TimedDataCollection::setupUI()
// 创建状态标签 // 创建状态标签
ui.statusLabel->setStyleSheet( ui.statusLabel->setStyleSheet(
"QLabel {" "QLabel {"
" background-color: #f0f0f0;" " background-color: #3856B8;"
" border: 1px solid #ccc;" " border: 1px solid #2f6bff;"
" border-radius: 4px;" " border-radius: 4px;"
" padding: 8px;" " padding: 8px;"
" font-size: 12px;" " font-size: 12px;"
@ -215,11 +215,11 @@ void TimedDataCollection::onErrorOccurred(const QString& error)
ui.statusLabel->setText(QString::fromLocal8Bit("错误: %1").arg(error)); ui.statusLabel->setText(QString::fromLocal8Bit("错误: %1").arg(error));
ui.statusLabel->setStyleSheet( ui.statusLabel->setStyleSheet(
"QLabel {" "QLabel {"
" background-color: #ffebee;" " background-color: #3856B8;"
" border: 1px solid #f44336;" " border: 1px solid #2f6bff;"
" border-radius: 4px;" " border-radius: 4px;"
" padding: 8px;" " padding: 8px;"
" color: #c62828;" " color: #e6eeff;"
"}" "}"
); );
@ -354,11 +354,11 @@ void TimedDataCollection::updateStatusBar()
styleSheet = styleSheet =
"QLabel {" "QLabel {"
" background-color: #e8f5e9;" " background-color: #3856B8;"
" border: 1px solid #4CAF50;" " border: 1px solid #2f6bff;"
" border-radius: 4px;" " border-radius: 4px;"
" padding: 8px;" " padding: 8px;"
" color: #2e7d32;" " color: #e6eeff;"
" font-weight: bold;" " font-weight: bold;"
"}"; "}";
} }
@ -381,8 +381,8 @@ void TimedDataCollection::updateStatusBar()
styleSheet = styleSheet =
"QLabel {" "QLabel {"
" background-color: #f5f5f5;" " background-color: #3856B8;"
" border: 1px solid #ccc;" " border: 1px solid #2f6bff;"
" border-radius: 4px;" " border-radius: 4px;"
" padding: 8px;" " padding: 8px;"
"}"; "}";
@ -466,11 +466,11 @@ void TimedDataCollection::startScheduler()
ui.statusLabel->setText(QString::fromLocal8Bit("调度器已启动,等待任务执行...")); ui.statusLabel->setText(QString::fromLocal8Bit("调度器已启动,等待任务执行..."));
ui.statusLabel->setStyleSheet( ui.statusLabel->setStyleSheet(
"QLabel {" "QLabel {"
" background-color: #fff3e0;" " background-color: #3856B8;"
" border: 1px solid #ff9800;" " border: 1px solid #2f6bff;"
" border-radius: 4px;" " border-radius: 4px;"
" padding: 8px;" " padding: 8px;"
" color: #e65100;" " color: #e6eeff;"
"}"); "}");
} }
} }
@ -492,11 +492,11 @@ void TimedDataCollection::stopScheduler()
ui.statusLabel->setText(QString::fromLocal8Bit("调度器已停止")); ui.statusLabel->setText(QString::fromLocal8Bit("调度器已停止"));
ui.statusLabel->setStyleSheet( ui.statusLabel->setStyleSheet(
"QLabel {" "QLabel {"
" background-color: #fce4ec;" " background-color: #3856B8;"
" border: 1px solid #e91e63;" " border: 1px solid #2f6bff;"
" border-radius: 4px;" " border-radius: 4px;"
" padding: 8px;" " padding: 8px;"
" color: #880e4f;" " color: #e6eeff;"
"}"); "}");
} }
} }

View File

@ -206,7 +206,7 @@ bool TimedDataCollectionDataStructuresReaderWriter::jsonToTimedTask(const QJsonO
TaskExecutor::TaskExecutor(QObject* parent) TaskExecutor::TaskExecutor(QObject* parent)
: QObject(parent) : QObject(parent)
, m_currentSubTaskIndex(0) , m_currentSubTaskIndex(-1)
, m_isRunning(false) , m_isRunning(false)
{ {
} }
@ -230,7 +230,7 @@ void TaskExecutor::execute(const TimedTask& task)
emit taskUpdated(m_task); emit taskUpdated(m_task);
m_currentSubTaskIndex = 0; m_currentSubTaskIndex = -1;
m_isRunning = true; m_isRunning = true;
qDebug() << "TaskExecutor: Starting task" << task.id; qDebug() << "TaskExecutor: Starting task" << task.id;
@ -322,7 +322,6 @@ void TaskExecutor::onSequenceComplete(int status)
case SubTaskType::SingleLensReflex: case SubTaskType::SingleLensReflex:
{ {
emit switchD65LampSignal(0); emit switchD65LampSignal(0);
emit switchSlrSignal(0);
break; break;
} }
case SubTaskType::DepthCamera: case SubTaskType::DepthCamera:
@ -360,11 +359,21 @@ void TaskExecutor::onSequenceComplete(int status)
void TaskExecutor::onBack2Origin() void TaskExecutor::onBack2Origin()
{ {
// 关闭单反电源
switch (m_task.subTasks[m_currentSubTaskIndex].type)
{
case SubTaskType::SingleLensReflex:
{
emit switchSlrSignal(0);
break;
}
}
// 检查是否还有更多子任务 // 检查是否还有更多子任务
m_currentSubTaskIndex++; int nestSubTaskIndex = m_currentSubTaskIndex + 1;
if (m_currentSubTaskIndex < m_task.subTasks.size()) { if (nestSubTaskIndex < m_task.subTasks.size()) {
// 执行下一个子任务 // 执行下一个子任务
if(m_task.subTasks[m_currentSubTaskIndex].type== SubTaskType::SingleLensReflex) if(m_task.subTasks[nestSubTaskIndex].type== SubTaskType::SingleLensReflex)
{ {
printMsgAndTime("Slr task,for weak up,please wait 135 seconds!"); printMsgAndTime("Slr task,for weak up,please wait 135 seconds!");
emit switchSlrSignal(0); emit switchSlrSignal(0);
@ -403,7 +412,10 @@ void TaskExecutor::onError(const QString& error)
void TaskExecutor::executeNextSubTask() void TaskExecutor::executeNextSubTask()
{ {
if (!m_isRunning || m_currentSubTaskIndex >= m_task.subTasks.size()) { m_currentSubTaskIndex++;
if (!m_isRunning || m_currentSubTaskIndex >= m_task.subTasks.size())
{
return; return;
} }

View File

@ -6,67 +6,200 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1182</width> <width>1299</width>
<height>576</height> <height>658</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>定时采集</string> <string>定时采集</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <property name="styleSheet">
<item row="0" column="0" colspan="3"> <string notr="true">QWidget #contentWidget
<widget class="QTreeView" name="taskTreeView"/> {
</item> background: #192770;
<item row="1" column="0"> /*border-radius: 8px 8px 8px 8px;*/
<widget class="QLineEdit" name="taskFileSelect_lineEdit"> border: 1px solid #2f6bff;
<property name="readOnly"> }
<bool>true</bool>
</property> QLineEdit {
</widget> background-color: #3856B8;
</item> color: #e6eeff;
<item row="1" column="1"> border: 1px solid #2f6bff;
<widget class="QPushButton" name="taskFileSelect_btn"> border-radius: 6px;
<property name="text"> padding: 4px 8px;
<string>...</string> min-width: 70px;
</property> min-height: 20px;
</widget> font-size: 13px;
</item> }
<item row="2" column="1">
<widget class="QPushButton" name="start_btn"> QLabel
<property name="text"> {
<string>开始调度</string> background: #243A82;
</property> color: rgb(255, 255, 255);
</widget> border: 1px solid #2f6bff;
</item> border-radius: 6px;
<item row="2" column="2"> }
<widget class="QPushButton" name="expandAll_btn">
<property name="text"> QPushButton
<string>展开</string> {
</property> /*width: 172px;
</widget> height: 56px;*/
</item> font: 10pt &quot;新宋体&quot;;
<item row="3" column="1"> background-color: qlineargradient(
<widget class="QPushButton" name="stop_btn"> spread:pad,
<property name="text"> x1:0.5, y1:0, x2:0.5, y2:1,
<string>停止调度</string> stop:0 #283D86,
</property> stop:1 #0F1A40
</widget> );
</item> color: white;
<item row="3" column="2"> border: none;
<widget class="QPushButton" name="collapseAll_btn"> padding: 8px 8px;
<property name="text"> border-radius: 4px;
<string>折叠</string> }
</property> QPushButton:hover
</widget> {
</item> background-color: qlineargradient(
<item row="4" column="0" colspan="3"> spread:pad,
<widget class="QLabel" name="statusLabel"> x1:0, y1:0, x2:1, y2:0,
<property name="text"> stop:0 #3A4875,
<string>任务统计</string> stop:1 #5F6B91
</property> );
<property name="alignment"> }
<set>Qt::AlignCenter</set> /* 按下时的效果 */
</property> QPushButton:pressed
{
background-color: qlineargradient(
spread:pad,
x1:0, y1:0, x2:1, y2:0,
stop:0 #1A254F,
stop:1 #3A466B
);
/* 可选:添加下压效果 */
padding-top: 9px;
padding-bottom: 7px;
}
</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QWidget" name="contentWidget" native="true">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="3">
<widget class="QTreeView" name="taskTreeView">
<property name="styleSheet">
<string notr="true">QTreeView
{
background-color: #121945;
border: 0px solid #444;
}
QHeaderView::section
{
background-color: #121945;
color: #ACCDFF;
padding: 6px;
}
QScrollBar:vertical {
background: #0b1440;
width: 10px;
border: 1px solid #1f2a5a;
}
QScrollBar:horizontal {
background: #0b1440;
height: 10px;
border: 1px solid #1f2a5a;
}
QScrollBar::handle:vertical,
QScrollBar::handle:horizontal {
background: #3a5bd6;
border-radius: 4px;
min-height: 20px;
min-width: 20px;
}
QScrollBar::handle:vertical:hover,
QScrollBar::handle:horizontal:hover {
background: #4f73ff;
}
</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="taskFileSelect_lineEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="taskFileSelect_btn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="start_btn">
<property name="text">
<string>开始调度</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="expandAll_btn">
<property name="text">
<string>展开</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="stop_btn">
<property name="text">
<string>停止调度</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="collapseAll_btn">
<property name="text">
<string>折叠</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="QLabel" name="statusLabel">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string>任务统计</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -288,7 +288,7 @@ QPushButton:pressed
}</string> }</string>
</property> </property>
<property name="text"> <property name="text">
<string>版本:3.0.2</string> <string>版本:3.1.0</string>
</property> </property>
</widget> </widget>
</item> </item>