From 2e0ee21631297a44eda8a64fda2af88c4fa27f75 Mon Sep 17 00:00:00 2001 From: Krad Date: Tue, 2 Aug 2022 11:07:16 +0800 Subject: [PATCH] Refactor QDicomViewer, extract toolbar DefaultToolBar class, refactor state -> only can build. --- src/Combinear.css | 77 +++ src/src/Common/QGlobals.h | 5 - src/src/UI/Manager/ImageViewManager.cpp | 10 +- src/src/UI/Manager/ImageViewManager.h | 4 +- src/src/UI/Widget/ToolBar/DefaultToolBar.cpp | 434 +++++++++++++++ src/src/UI/Widget/ToolBar/DefaultToolBar.h | 92 ++++ src/src/UI/Window/QDicomViewer.cpp | 541 +++++-------------- src/src/UI/Window/QDicomViewer.h | 46 +- src/src/UI/Window/QDicomViewer.ui | 14 +- 9 files changed, 777 insertions(+), 446 deletions(-) create mode 100644 src/src/UI/Widget/ToolBar/DefaultToolBar.cpp create mode 100644 src/src/UI/Widget/ToolBar/DefaultToolBar.h diff --git a/src/Combinear.css b/src/Combinear.css index 255c136..dad3207 100644 --- a/src/Combinear.css +++ b/src/Combinear.css @@ -50,6 +50,83 @@ QToolButton:disabled background-color: #222222; } +QToolBar QToolButton{ + min-width: 36px; + max-width: 36px; + min-height: 36px; + max-height: 36px; + /*qproperty-iconSize:36px 36px;*/ +} +QToolButton#groupButton { + qproperty-checkable:true; + qproperty-autoExclusive:true; +} + +QToolBar QToolButton[toolButtonStyle="2"]{ + min-width: 42px; + max-width: 42px; +} + +QToolButton#file { + qproperty-icon:url(":/InfiniteViewer/Icon/openfile.png"); +} +QToolButton#import { + qproperty-icon: url(":/InfiniteViewer/Icon/import.png") +} +QToolButton#save { + qproperty-icon: url(":/InfiniteViewer/Icon/save.png") +} +QToolButton#grid { + qproperty-icon: url(":/InfiniteViewer/Icon/grid.png") +} +QToolButton#sync { + qproperty-icon: url(":/InfiniteViewer/Icon/sync/sync_dis.png") +} +QToolButton#anonymize { + qproperty-icon: url(":/InfiniteViewer/Icon/anno.png") +} + +QToolButton#slice{qproperty-icon:url(":/InfiniteViewer/Icon/slice.png")} +QToolButton#window{qproperty-icon:url(":/InfiniteViewer/Icon/windowlevel.png")} +QToolButton#pan{qproperty-icon:url(":/InfiniteViewer/Icon/pan.png")} +QToolButton#zoom{qproperty-icon:url(":/InfiniteViewer/Icon/zoom.png")} +QToolButton#measure{qproperty-icon:url(":/InfiniteViewer/Icon/distance.png")} +QToolButton#clear{qproperty-icon:url(":/InfiniteViewer/Icon/trashbin.png")} + +QToolButton#flip{qproperty-icon:url(":/InfiniteViewer/Icon/flip.png")} +QToolButton#cine{qproperty-icon:url(":/InfiniteViewer/Icon/cine.png")} +QToolButton#fusion{qproperty-icon:url(":/InfiniteViewer/Icon/fusion.png")} +QToolButton#MPR{qproperty-icon:url(":/InfiniteViewer/Icon/MPR.png")} + +QToolButton#minimize{ + min-height: 25px; + max-height: 25px; + min-width: 25px; + max-width: 25px; + qproperty-icon:url(":/InfiniteViewer/Icon/minimize.png") +} +QToolButton#maximize{ + min-height: 25px; + max-height: 25px; + min-width: 25px; + max-width: 25px; + qproperty-icon:url(":/InfiniteViewer/Icon/maximize-restore.png") +} +QToolButton#close{ + min-height: 25px; + max-height: 25px; + min-width: 25px; + max-width: 25px; + qproperty-icon:url(":/InfiniteViewer/Icon/close.png") +} +QToolButton#fullscreen{ + min-height: 25px; + max-height: 25px; + min-width: 25px; + max-width: 25px; + qproperty-icon:url(":/InfiniteViewer/Icon/full_screen.png") +} + /*-----QMenu-----*/ QMenu { background-color: #f0f0f0; diff --git a/src/src/Common/QGlobals.h b/src/src/Common/QGlobals.h index d9f7cf0..aba064b 100644 --- a/src/src/Common/QGlobals.h +++ b/src/src/Common/QGlobals.h @@ -30,11 +30,6 @@ using namespace std; #define Project_OrganizationDomain "" - -#define SYNC_MANUAL_URL ":/InfiniteViewer/Icon/sync/sync_manual.png" -#define SYNC_AUTO_URL ":/InfiniteViewer/Icon/sync/sync_auto.png" -#define SYNC_DIS_URL ":/InfiniteViewer/Icon/sync/sync_dis.png" - #define CLOSE_URL ":/InfiniteViewer/Icon/close.png" #define MAX_URL ":/InfiniteViewer/Icon/max.png" diff --git a/src/src/UI/Manager/ImageViewManager.cpp b/src/src/UI/Manager/ImageViewManager.cpp index 8fdbf10..8eb0da7 100644 --- a/src/src/UI/Manager/ImageViewManager.cpp +++ b/src/src/UI/Manager/ImageViewManager.cpp @@ -334,11 +334,11 @@ void ImageViewManager::unloadFusion() { } } -void ImageViewManager::switchFusion() { +void ImageViewManager::switchFusion(bool fusion) { if (currentView) { - if (currentView->hasSeries() && currentView->isFusion()) { + if (currentView->hasSeries() && currentView->isFusion() && !fusion) { unloadFusion(); - } else { + } else if (fusion) { loadFusion(); } } @@ -357,3 +357,7 @@ bool ImageViewManager::checkViewFusion(DicomImageView *view) { return false; } +void ImageViewManager::clearCurrentView() { + currentView->viewCleared(); +} + diff --git a/src/src/UI/Manager/ImageViewManager.h b/src/src/UI/Manager/ImageViewManager.h index cb6ff67..218c787 100644 --- a/src/src/UI/Manager/ImageViewManager.h +++ b/src/src/UI/Manager/ImageViewManager.h @@ -76,6 +76,8 @@ public: void viewCleared(DicomImageView* view); + void clearCurrentView(); + void setInteractionMode(int InteractionMode); void renderAll(); @@ -92,7 +94,7 @@ public: void loadFusion(); - void switchFusion(); + void switchFusion(bool fusion); enum DoScope { Current, diff --git a/src/src/UI/Widget/ToolBar/DefaultToolBar.cpp b/src/src/UI/Widget/ToolBar/DefaultToolBar.cpp new file mode 100644 index 0000000..04e46ec --- /dev/null +++ b/src/src/UI/Widget/ToolBar/DefaultToolBar.cpp @@ -0,0 +1,434 @@ +// +// Created by Krad on 2022/8/1. +// +#include "DefaultToolBar.h" + +#include +#include +#include +#include "Rendering/Measure/Measure.h" + +#include "Common/QGlobals.h" +typedef tuple ActionProperty; +namespace { + const char *SYNC_MANUAL_URL = ":/InfiniteViewer/Icon/sync/sync_manual.png"; + const char *SYNC_AUTO_URL = ":/InfiniteViewer/Icon/sync/sync_auto.png"; + const char *SYNC_DIS_URL = ":/InfiniteViewer/Icon/sync/sync_dis.png"; + const int ACTION_COUNT = 7; + const ActionProperty MEASURE_ACTIIONS[ACTION_COUNT] = { + {"Length", ":/InfiniteViewer/Icon/distance.png", AnnotationActorType::RulerAnn}, + {"Angle", ":/InfiniteViewer/Icon/angle.png", AnnotationActorType::AngleAnn}, + {"Closed polygon", ":/InfiniteViewer/Icon/polygon.png", AnnotationActorType::ClosedPolygonAnn}, + {"Open polygon", ":/InfiniteViewer/Icon/polyline.png", AnnotationActorType::OpenPolygonAnn}, + {"Arrow", ":/InfiniteViewer/Icon/arrow.png", AnnotationActorType::ArrowAnn}, + {"Ellipse", ":/InfiniteViewer/Icon/ellipse.png", AnnotationActorType::EllipseAnn}, + {"Text", ":/InfiniteViewer/Icon/text.png", AnnotationActorType::TextAnn} + }; +} + +DefaultToolBar::DefaultToolBar(QWidget *parent) : QToolBar(parent) + , mBtnFile(new QToolButton(this)) + , mBtnImport(new QToolButton(this)) + , mBtnSave(new QToolButton(this)) + , mBtnGrid(new QToolButton(this)) + , mBtnSync(new QToolButton(this)) + , mBtnAnonymize(new QToolButton(this)) + , mBtnSlice(new QToolButton(this)) + , mBtnWindow(new QToolButton(this)) + , mBtnPan(new QToolButton(this)) + , mBtnZoom(new QToolButton(this)) + , mBtnMeasure(new QToolButton(this)) + , mBtnClear(new QToolButton(this)) + , mBtnFlip(new QToolButton(this)) + , mBtnCine(new QToolButton(this)) + , mBtnFusion(new QToolButton(this)) + , mBtnMPR(new QToolButton(this)) + , mBtnMinimize(new QToolButton(this)) + , mBtnMaximize(new QToolButton(this)) + , mBtnClose(new QToolButton(this)) + , mBtnFullScreen(new QToolButton(this)) + , mActionMinimize(nullptr) + , mActionMaximize(nullptr) + , mActionClose(nullptr) + , mActionFullScreen(nullptr) { + //init icons + mManualIcon.addFile(SYNC_MANUAL_URL); + mAutoIcon.addFile(SYNC_AUTO_URL); + mDisIcon.addFile(SYNC_DIS_URL); + initButtons(); +} + +DefaultToolBar::~DefaultToolBar() { + +} + +QAction* DefaultToolBar::initButton(QToolButton* button, const char* objectName) { + button->setObjectName(objectName); + button->setToolButtonStyle(Qt::ToolButtonIconOnly); + return addWidget(button); +} + +void DefaultToolBar::initGroupedButton(QToolButton* button, const char* objectName, QButtonGroup * group) { + button->setObjectName(objectName); + button->setCheckable(true); + button->setAutoExclusive(true); + group->addButton(button); + addWidget(button); +} + +void DefaultToolBar::initButtons() { + setContextMenuPolicy(Qt::ContextMenuPolicy::PreventContextMenu); + setFixedHeight(VCRHelper::toolbar_Height); + setMovable(false); + initButton(mBtnFile, "file"); + initButton(mBtnImport, "import"); + initButton(mBtnSave, "save"); + + addSeparator(); + + initButton(mBtnGrid, "grid"); + initButton(mBtnSync, "sync"); + initButton(mBtnAnonymize, "anonymize"); + + addSeparator(); + + QButtonGroup *modeGroup = new QButtonGroup(this); + initGroupedButton(mBtnSlice, "slice", modeGroup); + initGroupedButton(mBtnWindow, "window", modeGroup); + initGroupedButton(mBtnPan, "pan", modeGroup); + initGroupedButton(mBtnZoom, "zoom", modeGroup); + initGroupedButton(mBtnMeasure, "measure", modeGroup); + initButton(mBtnClear, "clear"); + addSeparator(); + + + initButton(mBtnFlip, "flip"); + initButton(mBtnCine, "cine"); + initButton(mBtnFusion, "fusion"); + initButton(mBtnMPR, "MPR"); + + QWidget *spacer = new QWidget(this); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + addWidget(spacer); + + mActionMinimize = initButton(mBtnMinimize, "minimize"); + mActionMaximize = initButton(mBtnMaximize, "maximize"); + mActionClose = initButton(mBtnClose, "close"); + mActionFullScreen = initButton(mBtnFullScreen, "fullscreen"); + + mActionMinimize->setVisible(false); + mActionMaximize->setVisible(false); + mActionClose->setVisible(false); + + SetupFileTool(); + SetupImportTool(); + SetupExportTool(); + SetupGridTool(); + SetupSyncTool(); + SetupModeTool(); + SetupTransformTool(); + SetupFusionTool(); + SetupCineTool(); + SetupEmptyTool(); + SetupScreenTool(); +} + +void DefaultToolBar::SetupFileTool() { + mBtnFile->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + // Menu + mBtnFile->setToolTip(QString("Open Dicom series from directory")); + QMenu *m; + m = new QMenu(this); + m->addAction(tr("Open DICOM folder"), this, &DefaultToolBar::openFolder); + + m->addAction(tr("Open DICOM file"), this, &DefaultToolBar::openFile); + + m->addSeparator(); + m->addAction(tr("Quit"), this, &DefaultToolBar::parentWindowClose); + mBtnFile->setPopupMode(QToolButton::MenuButtonPopup); + mBtnFile->setMenu(m); + + // connect + connect(mBtnFile, &QToolButton::clicked, this, &DefaultToolBar::openFolder); +} + +void DefaultToolBar::SetupImportTool() { + mBtnImport->setToolTip(QString("Search and download studies from PACS locations")); + connect(mBtnImport, &QToolButton::clicked, this, &DefaultToolBar::import); +} + +void DefaultToolBar::SetupExportTool() { + mBtnSave->setToolTip(QString("Export images")); + connect(mBtnSave, &QToolButton::clicked, this, &DefaultToolBar::save); +} + +void DefaultToolBar::SetupGridTool() { + mBtnGrid->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + mBtnGrid->setToolTip(QString("Split Screen")); + // connect + connect(mBtnGrid, &QToolButton::clicked, this, [=](){ + emit showGrid(mBtnGrid); + }); +} + +void DefaultToolBar::SetupSyncTool() { + mBtnSync->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + mBtnSync->setToolTip(QString("Toggle series synchronization")); + // Menu + QMenu * m = new QMenu(this); + + SyncState curst = SyncHelper::getSyncState(); + mActionSyncState = m->addAction(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[curst])); + mActionSyncState->setCheckable(false); + addSeparator(); + +#define ADD_SYNC_ITEM(index,text,type)\ + mSyncActions[index] = m->addAction(tr(text), this, [&](bool value) {\ + SyncHelper::setSyncItem(type, value);\ + });\ + mSyncActions[index]->setCheckable(true);\ + mSyncActions[index]->setChecked(false);\ + mSyncActions[index]->setDisabled(true); + + ADD_SYNC_ITEM(0,"Sychronize slice position",SyncItem::SLICE_POS) + ADD_SYNC_ITEM(1,"Sychronize zoom & pan",SyncItem::ZOOM_PAN) + ADD_SYNC_ITEM(2,"Sychronize window level & width",SyncItem::WIDTH_LEVEL) + + mBtnSync->setPopupMode(QToolButton::MenuButtonPopup); + mBtnSync->setMenu(m); + connect(mBtnSync, &QToolButton::clicked,[](){ + SyncHelper::setSyncState((SyncState)((SyncHelper::getSyncState()+1)%3)); + }); + connect(EventsCenter::Default(), &EventsCenter::SyncStateChanged, this, &DefaultToolBar::syncStateChanged); +} + +void DefaultToolBar::syncStateChanged() const { + switch (SyncHelper::getSyncState()) { + case AUTO_SYNC: +// mBtnSync->setIcon(mAutoIcon); + mActionSyncState->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[AUTO_SYNC])); + for (int i = 0; i < SYNC_ITEM_NUM; i++) { + mSyncActions[i]->setDisabled(false); + } + mSyncActions[SLICE_POS]->setChecked(SyncHelper::getSyncItem(SLICE_POS)); + mSyncActions[WIDTH_LEVEL]->setChecked(SyncHelper::getSyncItem(WIDTH_LEVEL)); + mSyncActions[ZOOM_PAN]->setChecked(SyncHelper::getSyncItem(ZOOM_PAN)); + break; + + case MANUAL_SYNC:{ +// mBtnSync->setIcon(mManualIcon); + mActionSyncState->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[MANUAL_SYNC])); + mSyncActions[SLICE_POS]->setChecked(SyncHelper::getSyncItem(SLICE_POS)); + mSyncActions[WIDTH_LEVEL]->setChecked(SyncHelper::getSyncItem(WIDTH_LEVEL)); + mSyncActions[ZOOM_PAN]->setChecked(SyncHelper::getSyncItem(ZOOM_PAN)); + break; + } + case DIS_SYNC: +// mBtnSync->setIcon(mDisIcon); + mActionSyncState->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[DIS_SYNC])); + for (int i = 0; i < SYNC_ITEM_NUM; i++) { + mSyncActions[i]->setChecked(false); + mSyncActions[i]->setDisabled(true); + } + break; + default: + break; + } +} + +void DefaultToolBar::SetupModeTool() { + mBtnWindow->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + mBtnWindow->setToolTip(QString("Adjust window level")); + connect(mBtnWindow, &QToolButton::clicked, this, [&] { + emit modeChanged(7); + }); + + // Menu + QMenu *m = new QMenu(this); + m->addAction(tr("Custom Window"), this, &DefaultToolBar::customWindow); + + auto action = m->addAction(tr("Negative"), this, &DefaultToolBar::negativeWindow); + action->setCheckable(true); + action->setChecked(false); + + mBtnWindow->setPopupMode(QToolButton::MenuButtonPopup); + mBtnWindow->setMenu(m); + + mBtnPan->setToolTip(QString("Pan image")); + connect(mBtnPan, &QToolButton::clicked, this, [&] { + emit modeChanged(5); + }); + + mBtnZoom->setToolTip(QString("Zoom image")); + connect(mBtnZoom, &QToolButton::clicked, this, [&] { + emit modeChanged(6); + }); + + mBtnSlice->setToolTip(QString("Browse series")); + connect(mBtnSlice, &QToolButton::clicked, this, [&] { + emit modeChanged(4); + }); + + SetupMeasureTool(); +} + +void DefaultToolBar::SetupAnnoTool() { + mBtnAnonymize->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + + //主要设置了四角标签的操作逻辑 + mBtnAnonymize->setToolTip(QString("Toggle annotations")); + //视窗操作,显隐脚注 + +// connect(mBtnAnonymize, &QToolButton::clicked, this, [=] { +// AnnoHelper::toggleAnno(); +// ui->viewContainer->getViewManager()->updateCornerInfoAll(); +// }); + + //视窗操作,显隐测量 + QMenu *m; + m = new QMenu(this); +// connect(m, &QMenu::triggered, this, [=] { +// //load data +// mActionHideMeasure->setChecked(Measure::GetHidden()); +// }); + //视窗操作,显隐测量 + mActionHideMeasure = m->addAction(tr("Hide all measurements"), this, [=](bool value) { + Measure::SetHidden(!mActionHideMeasure->isChecked()); +// ui->viewContainer->getViewManager()->renderAll(); + }); + mActionHideMeasure->setCheckable(true); + mActionHideMeasure->setChecked(false); + + m->addSeparator(); + + //视窗操作,匿名化 + mActionHidePatData = m->addAction(tr("Hide patient data"), this, [=] { + if (mActionHidePatData->isChecked()) { + AnnoHelper::PrivacyOn(); + } else { + AnnoHelper::PrivacyOff(); + } +// ui->viewContainer->getViewManager()->updateCornerInfoPrivacy(); + }); + mActionHidePatData->setCheckable(true); + mActionHidePatData->setChecked(false); + + m->addAction(tr("Show Dicom tags"), this, &DefaultToolBar::showMeta); + + mBtnAnonymize->setPopupMode(QToolButton::MenuButtonPopup); + mBtnAnonymize->setMenu(m); +} + +void DefaultToolBar::SetupMeasureTool() { +#define ADD_MEASURE_ACTION(index)\ + m->addAction(tr(std::get<0>(MEASURE_ACTIIONS[index])), this, [=] {\ + mBtnMeasure->setChecked(true);\ + QPixmap map(std::get<1>(MEASURE_ACTIIONS[index]));\ + mBtnMeasure->setIcon(QIcon(map));\ + }) +// MeasureHelper::setMeasureType(std::get<2>(MEASURE_ACTIIONS[index]));\ +// ui->viewContainer->getViewManager()->activeMeasure();\ + + +#define ADD_DEL_ACTION(text, type, func)\ + m->addAction(tr(text)); + + mBtnMeasure->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + mBtnMeasure->setToolTip(QString("Measurements")); + + connect(mBtnMeasure, &QToolButton::clicked, this, &DefaultToolBar::activeMeasure); + + QMenu *m; + m = new QMenu(this); + + for (int j = 0; j < ACTION_COUNT; ++j) { + ADD_MEASURE_ACTION(j); + } + m->addSeparator(); + ADD_DEL_ACTION("Delete selected", AnnotationActorType::DeleteSelectedAnn, deleteSelectedMeasure); + ADD_DEL_ACTION("Delete all in current slice", AnnotationActorType::DeleteSliceAnn, deleteCurrentSliceMeasure); + ADD_DEL_ACTION("Delete all in current series", AnnotationActorType::DeleteSeriesAnn, deleteCurrentSeriesMeasure); + mBtnMeasure->setPopupMode(QToolButton::MenuButtonPopup); + mBtnMeasure->setMenu(m); +} + +void DefaultToolBar::SetupFusionTool() { + mBtnFusion->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + mBtnFusion->setToolTip(QString("Fusion")); + connect(mBtnFusion, &QToolButton::clicked, this, &DefaultToolBar::fusion); + mBtnFusion->setCheckable(true); + QMenu *m = new QMenu(this); + m->addAction(tr("Reset Fusion"), [=](){ + mBtnFusion->setChecked(false); + emit fusion(false); + }); + mBtnFusion->setPopupMode(QToolButton::MenuButtonPopup); + mBtnFusion->setMenu(m); + mBtnFusion->setEnabled(false); +} + +void DefaultToolBar::SetupCineTool() { + mBtnCine->setToolTip(QString("Cine")); + mBtnCine->setCheckable(true); + connect(mBtnCine, &QToolButton::clicked, this, &DefaultToolBar::cine); +} + +void DefaultToolBar::SetupEmptyTool() { + mBtnClear->setToolTip(QString("Delete current series")); + connect(mBtnClear, &QToolButton::clicked, this, &DefaultToolBar::clear); +} + +void DefaultToolBar::SetupTransformTool() { + mBtnFlip->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + mBtnFlip->setToolTip(QString("Transformations")); + QMenu *m = new QMenu(this); + +#define ADD_TRANSFORM_ACTION(text,type)\ + m->addAction(tr(text), this, [&] {\ + emit transform(type);\ +}); + + ADD_TRANSFORM_ACTION("Rotate 90 CCW",ROTATE_90_CCW); + ADD_TRANSFORM_ACTION("Rotate 90 CW", ROTATE_90_CW); + ADD_TRANSFORM_ACTION("Rotate 180",ROTATE_180); + m->addSeparator(); + ADD_TRANSFORM_ACTION("Flip horizontal",H_FLIP); + ADD_TRANSFORM_ACTION("Flip vertical",V_FLIP); + m->addSeparator(); + ADD_TRANSFORM_ACTION("Clear transformations",CLEAR); + mBtnFlip->setPopupMode(QToolButton::MenuButtonPopup); + mBtnFlip->setMenu(m); + connect(mBtnFlip, &QPushButton::clicked, this,[=](){ + emit transform(H_FLIP); + }); +} + +void DefaultToolBar::SetupScreenTool() { + mBtnFullScreen->setToolTip(QString("Full screen")); + connect(mBtnFullScreen, &QToolButton::clicked, this, [=] { + mActionFullScreen->setVisible(false); + mActionMinimize->setVisible(true); + mActionMaximize->setVisible(true); + mActionClose->setVisible(true); + + emit parentWindowStateChange(Qt::WindowState::WindowFullScreen); + }); + + mBtnMaximize->setToolTip(QString("Exit full screen mode")); + connect(mBtnMaximize, &QToolButton::clicked, this, [=] { + mActionFullScreen->setVisible(true); + mActionMinimize->setVisible(false); + mActionMaximize->setVisible(false); + mActionClose->setVisible(false); + + emit parentWindowStateChange(Qt::WindowState::WindowMaximized); + }); + + mBtnMinimize->setToolTip(QString("Minimize")); + connect(mBtnMinimize, &QToolButton::clicked, this, [=] { + emit parentWindowStateChange(Qt::WindowState::WindowMinimized); + }); + + mBtnClose->setToolTip(QString("Close")); + connect(mBtnClose, &QToolButton::clicked, this, &DefaultToolBar::parentWindowClose); +} \ No newline at end of file diff --git a/src/src/UI/Widget/ToolBar/DefaultToolBar.h b/src/src/UI/Widget/ToolBar/DefaultToolBar.h new file mode 100644 index 0000000..45793d3 --- /dev/null +++ b/src/src/UI/Widget/ToolBar/DefaultToolBar.h @@ -0,0 +1,92 @@ +// +// Created by Krad on 2022/8/1. +// + +#ifndef OMEGAV_DEFAULTTOOLBAR_H +#define OMEGAV_DEFAULTTOOLBAR_H + +#include +#include "Common/QGlobals.h" + +class QButtonGroup; + +class DefaultToolBar : public QToolBar { + Q_OBJECT +public: + explicit DefaultToolBar(QWidget *parent = nullptr); + + ~DefaultToolBar(); +signals: + void openFile(); + void openFolder(); + void import(); + void save(); + void showGrid(QToolButton* btn); + void modeChanged(int mode); + void customWindow(); + void negativeWindow(); + void fusion(bool on = false); + void cine(bool on = false); + void activeMeasure(); + void clear(); + void parentWindowStateChange(Qt::WindowState state); + void parentWindowClose(); + void transform(TransFormType type); + void showMeta(); +private: + QAction *initButton(QToolButton *button, const char *objectName); + + void initGroupedButton(QToolButton *button, const char *objectName, QButtonGroup *group); + + void initButtons(); + void syncStateChanged() const; + + void SetupFileTool(); + void SetupImportTool(); + void SetupExportTool(); + void SetupGridTool(); + void SetupSyncTool(); + void SetupModeTool(); + void SetupAnnoTool(); + void SetupMeasureTool(); + void SetupFusionTool(); + void SetupCineTool(); + void SetupEmptyTool(); + void SetupTransformTool(); + void SetupScreenTool(); + + QIcon mManualIcon; + QIcon mAutoIcon; + QIcon mDisIcon; + QToolButton *mBtnFile; + QToolButton *mBtnImport; + QToolButton *mBtnSave; + QToolButton *mBtnGrid; + QToolButton *mBtnSync; + QToolButton *mBtnAnonymize; + QToolButton *mBtnSlice; + QToolButton *mBtnWindow; + QToolButton *mBtnPan; + QToolButton *mBtnZoom; + QToolButton *mBtnMeasure; + QToolButton *mBtnClear; + QToolButton *mBtnFlip; + QToolButton *mBtnCine; + QToolButton *mBtnFusion; + QToolButton *mBtnMPR; + QToolButton *mBtnMinimize; + QToolButton *mBtnMaximize; + QToolButton *mBtnClose; + QToolButton *mBtnFullScreen; + QAction *mActionMinimize; + QAction *mActionMaximize; + QAction *mActionClose; + QAction *mActionFullScreen; + QAction *mActionSyncState; + QAction *mActionHideMeasure; + QAction *mActionHidePatData; + QAction* mSyncActions[3]={nullptr,nullptr,nullptr}; +}; + + +#endif //OMEGAV_DEFAULTTOOLBAR_H diff --git a/src/src/UI/Window/QDicomViewer.cpp b/src/src/UI/Window/QDicomViewer.cpp index c63545d..382ac20 100644 --- a/src/src/UI/Window/QDicomViewer.cpp +++ b/src/src/UI/Window/QDicomViewer.cpp @@ -1,4 +1,4 @@ -#include "QDicomViewer.h" +#include "QDicomViewer.h" #include #include @@ -9,9 +9,12 @@ #include "Interaction/ActorDraggableInteractorStyle.h" #include "UI/Manager/ImageViewManager.h" +#include "UI/Widget/ToolBar/DefaultToolBar.h" #include "UI/Widget/Component/gridpopwidget.h" #include "UI/Widget/cine/pqVCRToolbar.h" + + QDicomViewer::QDicomViewer(QWidget *parent) : QMainWindow(parent), ui(new Ui::QDicomViewerClass), m_import(nullptr) { @@ -19,11 +22,6 @@ QDicomViewer::QDicomViewer(QWidget *parent) : QMainWindow(parent), this->statusBar()->showMessage(tr("Ready")); QWidget::setWindowTitle(Project_NAME); - //init icons - icon_manual.addFile(QStringLiteral(SYNC_MANUAL_URL)); - icon_auto.addFile(QStringLiteral(SYNC_AUTO_URL)); - icon_dis.addFile(QStringLiteral(SYNC_DIS_URL)); - this->Initial(); loadStyleSheet("Combinear"); @@ -48,8 +46,16 @@ QDicomViewer::~QDicomViewer() { } void QDicomViewer::Initial() { - this->createToolButton(); - this->SetupConnections(); + SetupFileTool(); + SetupImportTool(); + SetupExportTool(); + SetupGridTool(); + SetupSyncTool(); + SetupTransformTool(); + SetupEmptyTool(); + SetupScreenTool(); +// this->createToolButton(); +// this->SetupConnections(); } void QDicomViewer::loadStyleSheet(const QString &sheetName) { @@ -63,130 +69,39 @@ void QDicomViewer::loadStyleSheet(const QString &sheetName) { } void QDicomViewer::createToolButton() { -#define addbutton(name, png)\ - QToolButton* btn##name = new QToolButton(this);\ - {\ - QPixmap map(png);\ - btn##name->setIcon(QIcon(map));\ - btn##name->setMinimumSize(QSize(48, 48));\ - btn##name->setMaximumSize(QSize(48, 48));\ - btn##name->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);\ - this->ui->toolBar->addWidget(btn##name);\ - } -#define addGroupedButton(name, png, group)\ - QToolButton* btn##name = new QToolButton(this);\ - {\ - QPixmap map(png);\ - btn##name->setIcon(QIcon(map));\ - btn##name->setCheckable(true);\ - btn##name->setAutoExclusive(true);\ - btn##name->setMinimumSize(QSize(48, 48));\ - btn##name->setMaximumSize(QSize(48, 48));\ - btn##name->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);\ - group->addButton(btn##name);\ - this->ui->toolBar->addWidget(btn##name);\ - } + this->SetupFileTool(); + this->SetupImportTool(); + this->SetupExportTool(); -#define addbutton2(name, png)\ - QToolButton* btn##name = new QToolButton(this);\ - {\ - QPixmap map(png);\ - btn##name->setIcon(QIcon(map));\ - btn##name->setMinimumSize(QSize(25, 25));\ - btn##name->setMaximumSize(QSize(25, 25));\ - this->ui->toolBar->addWidget(btn##name); \ - } + this->SetupGridTool(); + this->SetupSyncTool(); + this->SetupAnnoTool(); - ui->toolBar->setContextMenuPolicy(Qt::ContextMenuPolicy::PreventContextMenu); - ui->toolBar->setFixedHeight(VCRHelper::toolbar_Height); - ui->toolBar->setMovable(false); - ui->toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); + this->SetupAdjustTool(); + this->SetupMeasureTool(); + this->SetupEmptyTool(); - addbutton(file, ":/InfiniteViewer/Icon/openfile.png") - addbutton(import, ":/InfiniteViewer/Icon/import.png") - addbutton(save, ":/InfiniteViewer/Icon/save.png") - this->ui->toolBar->addSeparator(); - - addbutton(grid, ":/InfiniteViewer/Icon/grid.png") - addbutton(sync, ":/InfiniteViewer/Icon/sync/sync_dis.png") - addbutton(anno, ":/InfiniteViewer/Icon/anno.png") - this->ui->toolBar->addSeparator(); - - QButtonGroup *modegroup = new QButtonGroup(this); - addGroupedButton(slice, ":/InfiniteViewer/Icon/slice.png", modegroup) - addGroupedButton(windowlevel, ":/InfiniteViewer/Icon/windowlevel.png", modegroup) - addGroupedButton(pan, ":/InfiniteViewer/Icon/pan.png", modegroup) - addGroupedButton(zoom, ":/InfiniteViewer/Icon/zoom.png", modegroup) - addGroupedButton(measure, ":/InfiniteViewer/Icon/distance.png", modegroup) - addbutton(empty, ":/InfiniteViewer/Icon/trashbin.png") - this->ui->toolBar->addSeparator(); + this->SetupTransformTool(); + this->SetupFusionTool(); + this->SetupCineTool(); - addbutton(flip, ":/InfiniteViewer/Icon/flip.png") - addbutton(cine, ":/InfiniteViewer/Icon/cine.png") - addbutton(fusion, ":/InfiniteViewer/Icon/fusion.png") - addbutton(MPR, ":/InfiniteViewer/Icon/MPR.png") - - QWidget *spacer = new QWidget(this); - spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - this->ui->toolBar->addWidget(spacer); - - act_num_of_minimize = ui->toolBar->actions().count(); - addbutton2(minimize, ":/InfiniteViewer/Icon/minimize.png") - - act_num_of_maximize = ui->toolBar->actions().count(); - addbutton2(maximize, ":/InfiniteViewer/Icon/maximize-restore.png") - - act_num_of_close = ui->toolBar->actions().count(); - addbutton2(close, ":/InfiniteViewer/Icon/close.png") - - act_num_of_fullscreen = ui->toolBar->actions().count(); - addbutton2(fullscreen, ":/InfiniteViewer/Icon/full_screen.png") - - ui->toolBar->actions().at(act_num_of_minimize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_maximize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_close)->setVisible(false); - - this->SetupFileTool(btnfile); - this->SetupImportTool(btnimport); - this->SetupExportTool(btnsave); - - this->SetupGridTool(btngrid); - this->SetupSyncTool(btnsync); - this->SetupAnnoTool(btnanno); - - this->SetupSliceTool(btnslice); - this->SetupAdjustTool(btnwindowlevel); - this->SetupPanTool(btnpan); - this->SetupZoomTool(btnzoom); - this->SetupMeasureTool(btnmeasure); - this->SetupEmptyTool(btnempty); - - this->SetupFlipTool(btnflip); - this->SetupFusionTool(btnfusion); - this->SetupCineTool(btncine); - - this->SetupFullScreenTool(btnfullscreen); - this->SetupMaximizeTool(btnmaximize); - this->SetupMinimizeTool(btnminimize); - this->SetupCloseTool(btnclose); - - connect(btnMPR, &QToolButton::clicked, [=](){ - SyncHelper::setSyncState(DIS_SYNC); - syncStateChanged(); - ui->viewContainer->getViewManager()->switchSliceOrientation(); - }); - btnMPR->setEnabled(false); - mprBtn = btnMPR; - fusionBtn = btnfusion; - connect(ui->viewContainer->getViewManager(), - &ImageViewManager::currentViewReload,[=](){ - btnfusion->setEnabled(false); - btnMPR->setEnabled(false); - SyncHelper::setSyncState(DIS_SYNC); - syncStateChanged(); - }); +// connect(btnMPR, &QToolButton::clicked, [=](){ +// SyncHelper::setSyncState(DIS_SYNC); +// syncStateChanged(); +// ui->viewContainer->getViewManager()->switchSliceOrientation(); +// }); +// btnMPR->setEnabled(false); +// mprBtn = btnMPR; +// fusionBtn = btnfusion; +// connect(ui->viewContainer->getViewManager(), +// &ImageViewManager::currentViewReload,[=](){ +// btnfusion->setEnabled(false); +// btnMPR->setEnabled(false); +// SyncHelper::setSyncState(DIS_SYNC); +// syncStateChanged(); +// }); worker.setManager(ui->viewContainer->getViewManager()); connect(ui->viewContainer->getViewManager(), @@ -197,111 +112,46 @@ void QDicomViewer::createToolButton() { workerManager.registerWorker(&worker); } -void QDicomViewer::SetupFullScreenTool(QToolButton *btnfullscreen) { - btnfullscreen->setToolTip(QString("Full screen")); - connect(btnfullscreen, &QToolButton::clicked, this, [=] { - ui->toolBar->actions().at(act_num_of_fullscreen)->setVisible(false); - ui->toolBar->actions().at(act_num_of_minimize)->setVisible(true); - ui->toolBar->actions().at(act_num_of_maximize)->setVisible(true); - ui->toolBar->actions().at(act_num_of_close)->setVisible(true); - - setWindowState(Qt::WindowState::WindowFullScreen); - }); +void QDicomViewer::SetupScreenTool() { + connect(ui->toolBar,&DefaultToolBar::parentWindowStateChange,this,&QDicomViewer::setWindowState); + connect(ui->toolBar,&DefaultToolBar::parentWindowClose, this, &QWidget::close); } -void QDicomViewer::SetupMaximizeTool(QToolButton *btnmaximize) { - btnmaximize->setToolTip(QString("Exit full screen mode")); - connect(btnmaximize, &QToolButton::clicked, this, [=] { +void QDicomViewer::SetupAnnoTool() { +// connect(annoBtn, &QToolButton::clicked, this, [=] { +// AnnoHelper::toggleAnno(); +// ui->viewContainer->getViewManager()->updateCornerInfoAll(); +// }); - ui->toolBar->actions().at(act_num_of_minimize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_maximize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_close)->setVisible(false); - ui->toolBar->actions().at(act_num_of_fullscreen)->setVisible(true); +// //视窗操作,显隐测量 +// m_measure_hidden_action = m->addAction(tr("Hide all measurements"), this, [=](bool value) { +// Measure::SetHidden(value); +// ui->viewContainer->getViewManager()->renderAll(); +// }); - setWindowState(Qt::WindowState::WindowMaximized); - }); -} - -void QDicomViewer::SetupMinimizeTool(QToolButton *btnminimize) { - btnminimize->setToolTip(QString("Minimize")); - connect(btnminimize, &QToolButton::clicked, this, [=] { - setWindowState(Qt::WindowState::WindowMinimized); - }); -} - -void QDicomViewer::SetupCloseTool(QToolButton *btnclose) { - btnclose->setToolTip(QString("Close")); - connect(btnclose, &QToolButton::clicked, this, &QWidget::close); -} - -void QDicomViewer::SetupAnnoTool(QToolButton *annoBtn) { - //主要设置了四角标签的操作逻辑 - annoBtn->setToolTip(QString("Toggle annotations")); - //视窗操作,显隐脚注 - - connect(annoBtn, &QToolButton::clicked, this, [=] { - AnnoHelper::toggleAnno(); - ui->viewContainer->getViewManager()->updateCornerInfoAll(); - }); - - //视窗操作,显隐测量 - QMenu *m; - m = new QMenu(this); - connect(m, &QMenu::triggered, this, [=] { - //load data - m_measure_hidden_action->setChecked(Measure::GetHidden()); - }); - //视窗操作,显隐测量 - m_measure_hidden_action = m->addAction(tr("Hide all measurements"), this, [=](bool value) { - Measure::SetHidden(value); - ui->viewContainer->getViewManager()->renderAll(); - }); - - m->addSeparator(); //视窗操作,匿名化 - m_patient_hidden_action = m->addAction(tr("Hide patient data"), this, [=] { - if (m_patient_hidden_action->isChecked()) { - AnnoHelper::PrivacyOn(); - } else { - AnnoHelper::PrivacyOff(); - } - ui->viewContainer->getViewManager()->updateCornerInfoPrivacy(); - }); - m_patient_hidden_action->setCheckable(true); - m_patient_hidden_action->setChecked(false); +// m_patient_hidden_action = m->addAction(tr("Hide patient data"), this, [=] { +// if (m_patient_hidden_action->isChecked()) { +// AnnoHelper::PrivacyOn(); +// } else { +// AnnoHelper::PrivacyOff(); +// } +// ui->viewContainer->getViewManager()->updateCornerInfoPrivacy(); +// }); +// m_patient_hidden_action->setCheckable(true); +// m_patient_hidden_action->setChecked(false); - m->addAction(tr("Show Dicom tags"), this, [&] { + connect(ui->toolBar,&DefaultToolBar::showMeta, this, [&] { DicomImageView *curV = ui->viewContainer->getCurrentView(); if (curV->hasSeries()) { curV->showMetaData(); } }); - - m_measure_hidden_action->setCheckable(true); - m_measure_hidden_action->setChecked(false); - - - annoBtn->setPopupMode(QToolButton::MenuButtonPopup); - annoBtn->setMenu(m); -} - - -namespace { - const int ACTION_COUNT = 7; - const ActionProperty MEASURE_ACTIIONS[ACTION_COUNT] = { - {"Length", ":/InfiniteViewer/Icon/distance.png", AnnotationActorType::RulerAnn}, - {"Angle", ":/InfiniteViewer/Icon/angle.png", AnnotationActorType::AngleAnn}, - {"Closed polygon", ":/InfiniteViewer/Icon/polygon.png", AnnotationActorType::ClosedPolygonAnn}, - {"Open polygon", ":/InfiniteViewer/Icon/polyline.png", AnnotationActorType::OpenPolygonAnn}, - {"Arrow", ":/InfiniteViewer/Icon/arrow.png", AnnotationActorType::ArrowAnn}, - {"Ellipse", ":/InfiniteViewer/Icon/ellipse.png", AnnotationActorType::EllipseAnn}, - {"Text", ":/InfiniteViewer/Icon/text.png", AnnotationActorType::TextAnn} - }; } //AnnotationActor执行相关 -void QDicomViewer::SetupMeasureTool(QToolButton *measureBtn) { +void QDicomViewer::SetupMeasureTool() { #define ADD_MEASURE_ACTION(index)\ m->addAction(tr(std::get<0>(MEASURE_ACTIIONS[index])), this, [=] {\ measureBtn->setChecked(true);\ @@ -321,23 +171,23 @@ void QDicomViewer::SetupMeasureTool(QToolButton *measureBtn) { curV->func();\ }\ }) - - measureBtn->setToolTip(QString("Measurements")); - - connect(measureBtn, &QToolButton::clicked, this, &QDicomViewer::executeActiveMeasure); - - QMenu *m; - m = new QMenu(this); - - for (int j = 0; j < ACTION_COUNT; ++j) { - ADD_MEASURE_ACTION(j); - } - m->addSeparator(); - ADD_DEL_ACTION("Delete selected", AnnotationActorType::DeleteSelectedAnn, deleteSelectedMeasure); - ADD_DEL_ACTION("Delete all in current slice", AnnotationActorType::DeleteSliceAnn, deleteCurrentSliceMeasure); - ADD_DEL_ACTION("Delete all in current series", AnnotationActorType::DeleteSeriesAnn, deleteCurrentSeriesMeasure); - measureBtn->setPopupMode(QToolButton::MenuButtonPopup); - measureBtn->setMenu(m); +// measureBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); +// measureBtn->setToolTip(QString("Measurements")); +// +// connect(measureBtn, &QToolButton::clicked, this, &QDicomViewer::executeActiveMeasure); +// +// QMenu *m; +// m = new QMenu(this); +// +// for (int j = 0; j < ACTION_COUNT; ++j) { +// ADD_MEASURE_ACTION(j); +// } +// m->addSeparator(); +// ADD_DEL_ACTION("Delete selected", AnnotationActorType::DeleteSelectedAnn, deleteSelectedMeasure); +// ADD_DEL_ACTION("Delete all in current slice", AnnotationActorType::DeleteSliceAnn, deleteCurrentSliceMeasure); +// ADD_DEL_ACTION("Delete all in current series", AnnotationActorType::DeleteSeriesAnn, deleteCurrentSeriesMeasure); +// measureBtn->setPopupMode(QToolButton::MenuButtonPopup); +// measureBtn->setMenu(m); } void QDicomViewer::executeActiveMeasure() { @@ -366,9 +216,8 @@ void QDicomViewer::executeActiveMeasure() { } //视窗操作,播放相关 -void QDicomViewer::SetupCineTool(QToolButton *cineBtn) { - cineBtn->setToolTip(QString("Cine")); - connect(cineBtn, &QToolButton::clicked, this, [&] { +void QDicomViewer::SetupCineTool() { + connect(ui->toolBar, &DefaultToolBar::cine, this, [&] { DicomImageView *curV = ui->viewContainer->getCurrentView(); if (curV->hasSeries()) { if (curV->IsCine()) { @@ -379,8 +228,6 @@ void QDicomViewer::SetupCineTool(QToolButton *cineBtn) { } } }); - - } void QDicomViewer::createVCRToolbar(DicomImageView *v) { @@ -395,51 +242,15 @@ void QDicomViewer::createVCRToolbar(DicomImageView *v) { } //视窗操作,fusion相关 -void QDicomViewer::SetupFusionTool(QToolButton *fusionBtn) { - fusionBtn->setToolTip(QString("Fusion")); - connect(fusionBtn, &QToolButton::clicked, ui->viewContainer->getViewManager(), &ImageViewManager::switchFusion); - QMenu *m = new QMenu(this); - m->addAction(tr("Reset Fusion"), ui->viewContainer->getViewManager(), &ImageViewManager::unloadFusion); - fusionBtn->setPopupMode(QToolButton::MenuButtonPopup); - fusionBtn->setMenu(m); - fusionBtn->setEnabled(false); -} - -//视窗操作,slice -void QDicomViewer::SetupSliceTool(QToolButton *sliceBtn) { - sliceBtn->setToolTip(QString("Browse series")); - connect(sliceBtn, &QToolButton::clicked, this, [&] { - ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_SLICING); - }); -} - -//视窗操作,pan -void QDicomViewer::SetupPanTool(QToolButton *panBtn) { - panBtn->setToolTip(QString("Pan image")); - connect(panBtn, &QToolButton::clicked, this, [&] { - ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_PAN); - }); -} - -//视窗操作,zoom -void QDicomViewer::SetupZoomTool(QToolButton *zoomBtn) { - zoomBtn->setToolTip(QString("Zoom image")); - connect(zoomBtn, &QToolButton::clicked, this, [&] { - ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_ZOOM); - }); +void QDicomViewer::SetupFusionTool() { + connect(ui->toolBar, &DefaultToolBar::fusion, ui->viewContainer->getViewManager(), &ImageViewManager::switchFusion); } //视窗操作,wwwl -void QDicomViewer::SetupAdjustTool(QToolButton *winlevelBtn) { - winlevelBtn->setToolTip(QString("Adjust window level")); - connect(winlevelBtn, &QToolButton::clicked, this, [&] { - ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_WINDOWLEVEL); - }); +void QDicomViewer::SetupAdjustTool() { + connect(ui->toolBar, &DefaultToolBar::modeChanged, ui->viewContainer->getViewManager(), &ImageViewManager::setInteractionMode); - // Menu - QMenu *m = new QMenu(this); - m->addAction(tr("Custom Window"), this, [=](bool value) { - winlevelBtn->setChecked(true); + connect(ui->toolBar, &DefaultToolBar::customWindow, [=]() { if (nullptr == m_customwin) { m_customwin = new Customwindow(this); } @@ -449,102 +260,62 @@ void QDicomViewer::SetupAdjustTool(QToolButton *winlevelBtn) { m_customwin->exec(); }); - m->addAction(tr("Negative"), this, [=](bool value) { - winlevelBtn->setChecked(true); + connect(ui->toolBar, &DefaultToolBar::negativeWindow, [=]() { DicomImageView *curV = ui->viewContainer->getViewManager()->getCurrentView(); if (curV != nullptr && curV->hasSeries()) { curV->negativeWindow(); } }); - winlevelBtn->setPopupMode(QToolButton::MenuButtonPopup); - winlevelBtn->setMenu(m); - } //视窗操作,clear -void QDicomViewer::SetupEmptyTool(QToolButton *emptyBtn) { - emptyBtn->setToolTip(QString("Delete current series")); - connect(emptyBtn, &QToolButton::clicked, ui->viewContainer->getCurrentView(), &DicomImageView::viewCleared); +void QDicomViewer::SetupEmptyTool() { + connect(ui->toolBar, &DefaultToolBar::clear, + ui->viewContainer->getViewManager(), &ImageViewManager::clearCurrentView); } //视窗操作,flip and rotation -void QDicomViewer::SetupFlipTool(QToolButton *flipBtn) { - flipBtn->setToolTip(QString("Transformations")); - QMenu *m = new QMenu(this); - -#define ADD_TRANSFORM_ACTION(text,func,...)\ - m->addAction(tr(text), this, [&] {\ - DicomImageView *curV = ui->viewContainer->getCurrentView();\ - if (curV != nullptr && curV->hasSeries()) {\ - curV->func(__VA_ARGS__);\ - }\ -}) - - ADD_TRANSFORM_ACTION("Rotate 90 CCW",rotateImage,90, ROTATE_90_CCW); - ADD_TRANSFORM_ACTION("Rotate 90 CW",rotateImage,-90, ROTATE_90_CW); - ADD_TRANSFORM_ACTION("Rotate 180",rotateImage,180, ROTATE_180); - m->addSeparator(); - ADD_TRANSFORM_ACTION("Flip horizontal",hFlipImage); - ADD_TRANSFORM_ACTION("Flip vertical",vFlipImage); - m->addSeparator(); - ADD_TRANSFORM_ACTION("Clear transformations",ClearTransformations); - flipBtn->setPopupMode(QToolButton::MenuButtonPopup); - flipBtn->setMenu(m); - connect(flipBtn, &QPushButton::clicked, this, [&] { +void QDicomViewer::SetupTransformTool() { + connect(ui->toolBar, &DefaultToolBar::transform,[=](TransFormType type){ DicomImageView *curV = ui->viewContainer->getCurrentView(); if (curV != nullptr && curV->hasSeries()) { - curV->rotateImage(90, ROTATE_90_CCW); + switch (type){ + case ROTATE_90_CCW: + curV->rotateImage(90,ROTATE_90_CCW); + break; + case ROTATE_90_CW: + curV->rotateImage(-90,ROTATE_90_CW); + break; + case ROTATE_180: + curV->rotateImage(180,ROTATE_180); + break; + case H_FLIP: + curV->hFlipImage(); + break; + case V_FLIP: + curV->vFlipImage(); + break; + case CLEAR: + curV->ClearTransformations(); + break; + default: + break; + } } }); } //视窗操作,sync mode -void QDicomViewer::SetupSyncTool(QToolButton *btn) { - syncBtn = btn; - syncBtn->setToolTip(QString("Toggle series synchronization")); - // Menu - QMenu * m = new QMenu(this); - - //QAction *a; - SyncState curst = SyncHelper::getSyncState(); - m_sync_state_action = m->addAction(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[curst]), this, - [&](bool value) { - }); - m_sync_state_action->setCheckable(false); - - this->ui->toolBar->addSeparator(); - -#define ADD_SYNC_ITEM(index,text,type)\ - m_sync_item_action[index] = m->addAction(tr(text), this, [&](bool value) {\ - SyncHelper::setSyncItem(type, value);\ - });\ - m_sync_item_action[index]->setCheckable(true);\ - m_sync_item_action[index]->setChecked(false);\ - m_sync_item_action[index]->setDisabled(true); - - ADD_SYNC_ITEM(0,"Sychronize slice position",SyncItem::SLICE_POS) - ADD_SYNC_ITEM(1,"Sychronize zoom & pan",SyncItem::ZOOM_PAN) - ADD_SYNC_ITEM(2,"Sychronize window level & width",SyncItem::WIDTH_LEVEL) - - syncBtn->setPopupMode(QToolButton::MenuButtonPopup); - syncBtn->setMenu(m); - - //loop click - connect(syncBtn, &QToolButton::clicked, this, - &QDicomViewer::switchSyncState); +void QDicomViewer::SetupSyncTool() { connect(EventsCenter::Default(), &EventsCenter::SyncStateChanged, this, &QDicomViewer::syncStateChanged); } -void QDicomViewer::switchSyncState(){ - SyncHelper::setSyncState((SyncState)((SyncHelper::getSyncState()+1)%3)); -} - void QDicomViewer::syncStateChanged() const { if (!syncBtn) return; switch (SyncHelper::getSyncState()) { case AUTO_SYNC: - syncBtn->setIcon(icon_auto); +// syncBtn->setIcon(mAutoIcon); m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[AUTO_SYNC])); for (int i = 0; i < SYNC_ITEM_NUM; i++) { m_sync_item_action[i]->setDisabled(false); @@ -555,7 +326,7 @@ void QDicomViewer::syncStateChanged() const { break; case MANUAL_SYNC:{ - syncBtn->setIcon(icon_manual); +// syncBtn->setIcon(mManualIcon); m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[MANUAL_SYNC])); m_sync_item_action[SLICE_POS]->setChecked(SyncHelper::getSyncItem(SLICE_POS)); m_sync_item_action[WIDTH_LEVEL]->setChecked(SyncHelper::getSyncItem(WIDTH_LEVEL)); @@ -563,7 +334,7 @@ void QDicomViewer::syncStateChanged() const { break; } case DIS_SYNC: - syncBtn->setIcon(icon_dis); +// syncBtn->setIcon(mDisIcon); m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[DIS_SYNC])); for (int i = 0; i < SYNC_ITEM_NUM; i++) { m_sync_item_action[i]->setChecked(false); @@ -576,12 +347,8 @@ void QDicomViewer::syncStateChanged() const { } //视窗操作?,file open相关 -void QDicomViewer::SetupFileTool(QToolButton *fileBtn) { - // Menu - fileBtn->setToolTip(QString("Open Dicom series from directory")); - QMenu *m; - m = new QMenu(this); - m->addAction(tr("Open DICOM folder"), this, [&] { +void QDicomViewer::SetupFileTool() { + connect(ui->toolBar,&DefaultToolBar::openFolder, [&] { QString p = QFileDialog::getExistingDirectory(this, tr("Open dicom directory"), m_qs.value("DIR_PATH_ID").toString()); if (!p.isEmpty()) { @@ -590,7 +357,7 @@ void QDicomViewer::SetupFileTool(QToolButton *fileBtn) { } }); - m->addAction(tr("Open DICOM file"), this, [&] { + connect(ui->toolBar,&DefaultToolBar::openFile, [&] { //QSettings s; //QString p = s.value(FILE_PATH_ID).toString(); QString fn = QFileDialog::getOpenFileName(this, tr("Open dicom files"), m_qs.value("FILE_PATH_ID").toString()); @@ -599,26 +366,11 @@ void QDicomViewer::SetupFileTool(QToolButton *fileBtn) { openDICOM(fn.toLocal8Bit().toStdString(), FILE_OPEN_MODE); } }); - - m->addSeparator(); - m->addAction(tr("Quit"), this, &QDicomViewer::close); - fileBtn->setPopupMode(QToolButton::MenuButtonPopup); - fileBtn->setMenu(m); - - // connect - connect(fileBtn, &QToolButton::clicked, this, [&] { - QString p = QFileDialog::getExistingDirectory(this, tr("Open dicom directory"), - m_qs.value("DIR_PATH_ID").toString()); - if (!p.isEmpty()) { - m_qs.setValue("DIR_PATH_ID", p); - openDICOM(p.toLocal8Bit().toStdString(), DIR_OPEN_MODE); - } - }); } -void QDicomViewer::SetupImportTool(QToolButton *importBtn) { - importBtn->setToolTip(QString("Search and download studies from PACS locations")); - connect(importBtn, &QToolButton::clicked, this, [&] { +void QDicomViewer::SetupImportTool() { + + connect(ui->toolBar, &DefaultToolBar::import, this, [&] { if (nullptr == m_import) { m_import = new ImportWidget(this); connect(m_import, &ImportWidget::sigMoveDone, this, &QDicomViewer::openDICOMFromPACS); @@ -627,49 +379,32 @@ void QDicomViewer::SetupImportTool(QToolButton *importBtn) { }); } -void QDicomViewer::SetupExportTool(QToolButton *saveBtn) { - saveBtn->setToolTip(QString("Export images")); - connect(saveBtn, &QToolButton::clicked, this, [=] { +void QDicomViewer::SetupExportTool() { + + connect(ui->toolBar, &DefaultToolBar::save, this, [=] { if (nullptr == exportDialog) { exportDialog = new ExportDialog(this); - //exportDialog->setViewContainer(ui->viewContainer); exportDialog->setCurView(ui->viewContainer->getCurrentView()); exportDialog->setModal(false); } exportDialog->show(); - }); } void QDicomViewer::displayThumbnailBar(bool value) { - VCRHelper::setThumbnailbar(value); - ui->thumbnailBar->setVisible(value); - m_preview_display_action->setChecked(value); +// VCRHelper::setThumbnailbar(value); +// ui->thumbnailBar->setVisible(value); +// m_preview_display_action->setChecked(value); } -void QDicomViewer::SetupGridTool(QToolButton *gridBtn) { - // Menu - //qDebug() << &gridBtn; - gridBtn->setToolTip(QString("Split Screen")); - QMenu *m; - m = new QMenu(this); - m_preview_display_action = m->addAction(tr("Preview bar"), this, [&](bool value) { - displayThumbnailBar(value); - - }); - m_preview_display_action->setCheckable(true); - m_preview_display_action->setChecked(false); - - gridBtn->setPopupMode(QToolButton::MenuButtonPopup); - gridBtn->setMenu(m); +void QDicomViewer::SetupGridTool() { // connect - connect(gridBtn, &QToolButton::clicked, this, [=] { + connect(ui->toolBar, &DefaultToolBar::showGrid, this, [=](QToolButton* btn) { // auto delete while hidden - //qDebug() << &gridBtn; - GridPopWidget *gpw = new GridPopWidget(gridBtn); + GridPopWidget *gpw = new GridPopWidget(btn); connect(gpw, &GridPopWidget::Signal_ViewLayout, ui->viewContainer, &ViewContainerWidget::viewLayoutChanged); - gpw->move(this->geometry().topLeft() + gridBtn->geometry().bottomLeft() + QPoint(5, 5)); + gpw->move(this->geometry().topLeft() + btn->geometry().bottomLeft() + QPoint(5, 5)); gpw->show(); }); } diff --git a/src/src/UI/Window/QDicomViewer.h b/src/src/UI/Window/QDicomViewer.h index 0b2923f..0528f18 100644 --- a/src/src/UI/Window/QDicomViewer.h +++ b/src/src/UI/Window/QDicomViewer.h @@ -9,7 +9,6 @@ #include "UI/Manager/ImageViewStateCheckWorker.h" #include "UI/Widget/Measure/pqFontPropertyWidget.h" -typedef tuple ActionProperty; /** * @brief 主窗口Class @@ -48,30 +47,24 @@ private: * 用于设置ToolButton相关的属性(文字、图标、槽等)的一组函数 * @{ */ - void SetupFileTool(QToolButton* fileBtn); - void SetupImportTool(QToolButton* importBtn); - void SetupExportTool(QToolButton *saveBtn); + void SetupFileTool(); + void SetupImportTool(); + void SetupExportTool(); - void SetupGridTool(QToolButton *gridBtn); - void SetupSyncTool(QToolButton *syncBtn); - void SetupAnnoTool(QToolButton *annoBtn); - - void SetupSliceTool(QToolButton* sliceBtn); - void SetupAdjustTool(QToolButton *winlevelBtn); - void SetupPanTool(QToolButton* panBtn); - void SetupZoomTool(QToolButton* zoomBtn); - void SetupMeasureTool(QToolButton *measureBtn); + void SetupGridTool(); + void SetupSyncTool(); + void SetupAnnoTool(); - void SetupFlipTool(QToolButton *flipBtn); - void SetupFusionTool(QToolButton* fusionBtn); - void SetupCineTool(QToolButton* cineBtn); - void SetupEmptyTool(QToolButton* emptyBtn); + void SetupAdjustTool(); + void SetupMeasureTool(); + + void SetupTransformTool(); + void SetupFusionTool(); + void SetupCineTool(); + void SetupEmptyTool(); - void SetupFullScreenTool(QToolButton *btnfullscreen); - void SetupMaximizeTool(QToolButton *btnmaximize); - void SetupMinimizeTool(QToolButton *btnminimize); - void SetupCloseTool(QToolButton *btnclose); + void SetupScreenTool(); //@} /** @@ -104,9 +97,8 @@ private: */ void createVCRToolbar(DicomImageView *v); - QIcon icon_manual; - QIcon icon_auto; - QIcon icon_dis; + void resetToolBarButtons(ViewFunctionState state); + QToolButton* syncBtn = nullptr; QToolButton* fusionBtn = nullptr; QToolButton* mprBtn = nullptr; @@ -114,12 +106,7 @@ private: QAction* m_sync_state_action; QAction* m_measure_hidden_action; QAction* m_patient_hidden_action; - QAction* m_preview_display_action; - int act_num_of_close; - int act_num_of_maximize; - int act_num_of_fullscreen; - int act_num_of_minimize; ExportDialog *exportDialog = nullptr; ImportWidget *m_import =nullptr; @@ -132,6 +119,5 @@ private: ImageViewStateCheckWorker worker; void syncStateChanged() const; - void switchSyncState(); }; diff --git a/src/src/UI/Window/QDicomViewer.ui b/src/src/UI/Window/QDicomViewer.ui index 649b6f4..5cb41ee 100644 --- a/src/src/UI/Window/QDicomViewer.ui +++ b/src/src/UI/Window/QDicomViewer.ui @@ -125,7 +125,7 @@ true - + toolBar @@ -152,11 +152,17 @@ 1 - ThumbnailBarWidget - QWidget -
UI/Widget/thumbnailbarwidget.h
+ DefaultToolBar + QToolBar +
UI/Widget/ToolBar/DefaultToolBar.h
1
+ + ThumbnailBarWidget + QWidget +
UI/Widget/Thumbnail/thumbnailbarwidget.h
+ 1 +