添加自定义tabBar和tab,实现拖动和样式定制

This commit is contained in:
duanshengchao 2024-11-05 09:24:21 +08:00
parent da11c76abd
commit 3c818a3e14
11 changed files with 604 additions and 217 deletions

View File

@ -23,6 +23,8 @@ set(H_HEADER_FILES
include/mainWindow.h include/mainWindow.h
include/customBorderContainer.h include/customBorderContainer.h
include/customMenu.h include/customMenu.h
include/customTab.h
include/customTabBar.h
include/functionNavigationBar.h include/functionNavigationBar.h
include/dvieMainWindow.h include/dvieMainWindow.h
include/tccMainWindow.h include/tccMainWindow.h
@ -45,6 +47,8 @@ set(CPP_SOURCE_FILES
source/mainWindow.cpp source/mainWindow.cpp
source/customBorderContainer.cpp source/customBorderContainer.cpp
source/customMenu.cpp source/customMenu.cpp
source/customTab.cpp
source/customTabBar.cpp
source/functionNavigationBar.cpp source/functionNavigationBar.cpp
source/dvieMainWindow.cpp source/dvieMainWindow.cpp
source/tccMainWindow.cpp source/tccMainWindow.cpp
@ -76,6 +80,11 @@ set(UI_FILES
ui/dateTimeSelectionPanel.ui ui/dateTimeSelectionPanel.ui
) )
set(UTIL_FILES
util/TimeLine/timeLineWidget.h
util/TimeLine/timeLineWidget.cpp
)
# #
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
@ -85,6 +94,7 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
${H_HEADER_FILES} ${H_HEADER_FILES}
${CPP_SOURCE_FILES} ${CPP_SOURCE_FILES}
${UI_FILES} ${UI_FILES}
${UTIL_FILES}
resource/PowerMaster.qrc resource/PowerMaster.qrc
) )
# Define target properties for Android with Qt 6 as: # Define target properties for Android with Qt 6 as:
@ -97,6 +107,7 @@ else()
${H_HEADER_FILES} ${H_HEADER_FILES}
${CPP_SOURCE_FILES} ${CPP_SOURCE_FILES}
${UI_FILES} ${UI_FILES}
${UTIL_FILES}
resource/PowerMaster.qrc resource/PowerMaster.qrc
) )
# Define properties for Android with Qt 5 after find_package() calls as: # Define properties for Android with Qt 5 after find_package() calls as:
@ -106,6 +117,7 @@ else()
${H_HEADER_FILES} ${H_HEADER_FILES}
${CPP_SOURCE_FILES} ${CPP_SOURCE_FILES}
${UI_FILES} ${UI_FILES}
${UTIL_FILES}
resource/PowerMaster.qrc resource/PowerMaster.qrc
) )
endif() endif()

View File

@ -9,7 +9,7 @@ class CustomMenu : public QMenu
public: public:
CustomMenu(QWidget *parent = nullptr); CustomMenu(QWidget *parent = nullptr);
~CustomMenu(); virtual ~CustomMenu();
bool mouseIsInside() {return m_bMouseInside;} bool mouseIsInside() {return m_bMouseInside;}

47
include/customTab.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef CUSTOMTAB_H
#define CUSTOMTAB_H
#include <QFrame>
class QLabel;
class QBoxLayout;
class CustomTab : public QFrame
{
Q_OBJECT
public:
CustomTab(QWidget *parent = nullptr);
virtual ~CustomTab();
void setActive(bool);
void setText(const QString&);
QString text();
void setIcon(const QIcon&);
void setTabBar(const QString);
QString tabBar();
signals:
void clicked();
protected:
void mousePressEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
private:
QIcon m_Icon;
QSize m_IconSize;
QLabel* m_pIconLabel;
QLabel* m_pTitle;
QBoxLayout* m_pLayout;
QString m_strTabBar; //所在的tabBar
QPoint m_pStartPos;
bool m_bLeftButtonPressed;
bool m_bDragging;
};
#endif

43
include/customTabBar.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef CUSTOMTABBAR_H
#define CUSTOMTABBAR_H
#include <QScrollArea>
class QBoxLayout;
class CustomTab;
class CustomTabBar : public QScrollArea
{
Q_OBJECT
public:
CustomTabBar(QWidget *parent = nullptr);
virtual ~CustomTabBar();
//void insertTab(int, CustomTab*);
void addTab(CustomTab*);
void removeTab(CustomTab*);
CustomTab* tab(int);
protected:
void dragEnterEvent(QDragEnterEvent* event) override;
void dragMoveEvent(QDragMoveEvent* event) override;
void dragLeaveEvent(QDragLeaveEvent* event) override;
void dropEvent(QDropEvent* event) override;
private:
int count();
public slots:
void onTabClicked();
signals:
void tabMoved(int, int);
private:
QWidget* m_pTabsContainerWidget;
QBoxLayout* m_pTabsLayout;
int m_nCurrentIndex;
QWidget* m_pPosMarking;
};
#endif

View File

@ -1,13 +1,12 @@
#ifndef DASHBOARD_H #ifndef DASHBOARD_H
#define DASHBOARD_H #define DASHBOARD_H
#include "qboxlayout.h"
#include <QObject> #include <QObject>
class QMdiArea; class CustomTab;
class QPushButton;
class QMenu; class QMenu;
class DataPanel; class DataPanel;
class Dashboard : public QObject class Dashboard : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -18,17 +17,16 @@ public:
const QString& getName(); const QString& getName();
void setName(const QString&); void setName(const QString&);
QPushButton* tabButton(); void setDisplayAreaLayout(QHBoxLayout*);
CustomTab* tab();
QWidget* displayArea(); QWidget* displayArea();
void setSelected(bool); void setActive(bool);
void addPanel(const QString&); void addPanel(const QString&);
void removePanel(const QString&); void removePanel(const QString&);
void deleteSubWidgets();
private:
void updateTabButtonSize();
public slots: public slots:
void contextMenu_tabButton(const QPoint&); void contextMenu_tab(const QPoint&);
void onAction_rename(); void onAction_rename();
void onAction_remove(); void onAction_remove();
@ -40,9 +38,10 @@ signals:
private: private:
QString m_strName; QString m_strName;
QPushButton* m_pTabButton; CustomTab* m_pTab;
QMenu* m_pTabBtnMenu; QMenu* m_pTabMenu;
QWidget* m_pDisplayArea; QWidget* m_pDisplayArea;
QHBoxLayout* m_pDisplayAreaLayout;
QList<DataPanel*> m_dataPanels; QList<DataPanel*> m_dataPanels;
int m_nPanenlNameNumber; int m_nPanenlNameNumber;
}; };

View File

@ -12,6 +12,7 @@ QT_END_NAMESPACE
class TransparentMask; class TransparentMask;
class MessageDialog; class MessageDialog;
class CustomTabBar;
class Dashboard; class Dashboard;
class DashboardNamingDialog; class DashboardNamingDialog;
class PanelSelectionDialog; class PanelSelectionDialog;
@ -29,7 +30,8 @@ private:
void showTransparentMask(); void showTransparentMask();
void hideTransparentMask(); void hideTransparentMask();
void addADashboard(const QString&); void addDashboard(const QString&);
void removeDashboard(const QString&, bool);
void setCurrentDashboard(const QString&); void setCurrentDashboard(const QString&);
protected: protected:
@ -53,6 +55,7 @@ public slots:
void onSignal_renameDashboard(); void onSignal_renameDashboard();
void onSignal_removeDashboard(); void onSignal_removeDashboard();
void onSignal_dashboardNaming(const QString&, const QString&); void onSignal_dashboardNaming(const QString&, const QString&);
void onSignal_dashboardTabMoved(int, int); //拖动tab引发了位置变化
void onSignal_panelSelectResult(const QString&); void onSignal_panelSelectResult(const QString&);
void onSignal_viewHistoricalData(QDateTime); void onSignal_viewHistoricalData(QDateTime);
@ -61,8 +64,10 @@ private:
Ui::dvieMainWindow* ui; Ui::dvieMainWindow* ui;
TransparentMask* m_pTransparentMask; TransparentMask* m_pTransparentMask;
MessageDialog* m_pMessageDialog; MessageDialog* m_pMessageDialog;
CustomTabBar* m_pDashboardTabBar;
QList<Dashboard*> m_listDashboard; QList<Dashboard*> m_listDashboard;
Dashboard* m_curSelectedDashboard; Dashboard* m_curActiveDashboard;
Dashboard* m_curOperationDashboard; Dashboard* m_curOperationDashboard;
DashboardNamingDialog* m_pDashboardNamingDialog; DashboardNamingDialog* m_pDashboardNamingDialog;

169
source/customTab.cpp Normal file
View File

@ -0,0 +1,169 @@
#include "customTab.h"
#include <QLabel>
#include <QBoxLayout>
#include <QMouseEvent>
#include <QDrag>
#include <QMimeData>
#include <QApplication>
CustomTab::CustomTab(QWidget* parent)
:QFrame(parent)
{
setContextMenuPolicy(Qt::CustomContextMenu);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setStyleSheet("QLabel{\n"
" color:rgb(250,250,250);\n"
" font:600 11pt \"微软雅黑\";\n"
" border:0px;\n"
" background-color:transparent;\n"
"}\n");
m_bLeftButtonPressed = false;
m_bDragging = false;
m_pTitle = new QLabel(this);
m_pTitle->setAlignment(Qt::AlignCenter);
m_IconSize = QSize(15,15);
m_pIconLabel = new QLabel(this);
m_pIconLabel->setMinimumSize(m_IconSize);
m_pIconLabel->setMaximumSize(m_IconSize);
QBoxLayout* iconLayout = new QBoxLayout(QBoxLayout::TopToBottom);
iconLayout->setContentsMargins(0, 1, 0, 0);
iconLayout->addWidget(m_pIconLabel);
QSpacerItem* spacer = new QSpacerItem(10, 40, QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Expanding);
iconLayout->addSpacerItem(spacer);
m_pLayout = new QBoxLayout(QBoxLayout::LeftToRight);
m_pLayout->setContentsMargins(15, 0, 0, 0);
m_pLayout->setSpacing(1);
m_pLayout->addWidget(m_pTitle);
m_pLayout->addLayout(iconLayout);
setLayout(m_pLayout);
m_strTabBar = "";
}
CustomTab::~CustomTab()
{
}
void CustomTab::mousePressEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
emit clicked();
m_pStartPos = event->pos();
m_bLeftButtonPressed = true;
}
QFrame::mousePressEvent(event);
}
void CustomTab::mouseMoveEvent(QMouseEvent* event)
{
if(m_bLeftButtonPressed && !m_bDragging)
{
//qDebug() << "dragging";
int distance = (event->pos() - m_pStartPos).manhattanLength();
if (distance >= QApplication::startDragDistance())
{
QPoint hotSpot = event->pos();
QByteArray data;
QDataStream dataStream(&data, QIODevice::WriteOnly);
dataStream << text() << m_strTabBar;
QMimeData *mimeData = new QMimeData;
mimeData->setData("customTabDrag", data);
QDrag* drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(grab()); //通过render绘制的pixmap会有噪点直接通过grab获取效果更好
drag->setHotSpot(hotSpot);
m_bDragging = true;
Qt::DropAction dropAction = drag->exec();
//exec之后的语句都会在drg操作完成之后(鼠标抬起)执行
delete drag;
m_bLeftButtonPressed = false;
m_bDragging = false;
}
}
QFrame::mouseMoveEvent(event);
}
void CustomTab::mouseReleaseEvent(QMouseEvent* event)
{
//如果没有拖动事件发生,在这里处理相关逻辑
m_bLeftButtonPressed = false;
QFrame::mouseReleaseEvent(event);
}
void CustomTab::setActive(bool bActive)
{
QString strStyleSheet = "";
if(bActive)
strStyleSheet = "QFrame{\n"
" border-bottom:3px solid rgb(67,160,249);\n"
"}\n"
"QFrame:hover{\n"
" background-color:rgba(60, 60, 60, 150);\n"
"}\n"
"QLabel{\n"
" color:rgb(250,250,250);\n"
" font:600 11pt \"微软雅黑\";\n"
" border:0px;\n"
"}\n"
"QLabel:hover{\n"
" background-color:transparent;"
"}\n";
else
strStyleSheet = "QFrame{\n"
" border-bottom:0px;\n"
"}\n"
"QFrame:hover{\n"
" background-color:rgba(60, 60, 60, 150);\n"
"}\n"
"QLabel{\n"
" color:rgb(250,250,250);\n"
" font:600 11pt \"微软雅黑\";\n"
" border:0px;\n"
"}\n"
"QLabel:hover{\n"
" background-color:transparent;\n"
"}\n";
setStyleSheet(strStyleSheet);
}
void CustomTab::setText(const QString& strTitle)
{
m_pTitle->setText(strTitle);
QFontMetrics metrics(m_pTitle->font());
QRect rect = metrics.boundingRect(m_pTitle->text());
m_pTitle->setMinimumSize(rect.width() + 10, 0);
m_pTitle->setMaximumSize(rect.width() + 10, 1660);
setObjectName("dashboardTab_" + strTitle);
}
QString CustomTab::text()
{
return m_pTitle->text();
}
void CustomTab::setIcon(const QIcon& icon)
{
if(icon.isNull())
m_pIconLabel->clear();
else
m_pIconLabel->setPixmap(icon.pixmap(m_IconSize));
}
void CustomTab::setTabBar(const QString strBar)
{
m_strTabBar = strBar;
}
QString CustomTab::tabBar()
{
return m_strTabBar;
}

172
source/customTabBar.cpp Normal file
View File

@ -0,0 +1,172 @@
#include "customTabBar.h"
#include "customTab.h"
#include <QBoxLayout>
#include <QDragEnterEvent>
#include <QMimeData>
CustomTabBar::CustomTabBar(QWidget* parent)
:QScrollArea(parent)
{
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setFrameStyle(QFrame::NoFrame);
setWidgetResizable(true);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
m_pPosMarking = new QWidget(this);
m_pPosMarking->setStyleSheet("QWidget{\n"
" border:0px;\n"
" background-color:rgb(200,200,200);\n"
"}\n");
m_pPosMarking->setMaximumWidth(3);
m_pPosMarking->setMinimumWidth(3);
m_pPosMarking->hide();
m_nCurrentIndex = -1;
m_pTabsContainerWidget = new QWidget(this);
m_pTabsContainerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_pTabsContainerWidget->setObjectName("tabsContainerWidget");
m_pTabsLayout = new QBoxLayout(QBoxLayout::LeftToRight);
m_pTabsLayout->setContentsMargins(0, 0, 0, 0);
m_pTabsLayout->setSpacing(0);
m_pTabsLayout->addStretch(1);
m_pTabsContainerWidget->setLayout(m_pTabsLayout);
setWidget(m_pTabsContainerWidget);
setFocusPolicy(Qt::NoFocus);
setAcceptDrops(true);
}
CustomTabBar::~CustomTabBar()
{
}
void CustomTabBar::dragEnterEvent(QDragEnterEvent* event)
{
const QMimeData* mimeData = event->mimeData();
if( mimeData->hasFormat("customTabDrag") )
{
event->acceptProposedAction();
//qDebug() << "dragEnterEvent";
}
else
event->ignore();
}
void CustomTabBar::dragMoveEvent(QDragMoveEvent* event)
{
//qDebug() << "dragMoveEvent";
event->acceptProposedAction();
int toIndex = -1;
int lastWidgetIndex = m_pTabsLayout->count() - 2;
QWidget* lastWidget = m_pTabsLayout->itemAt(lastWidgetIndex)->widget();
if(lastWidget && event->position().x() > lastWidget->geometry().right()) //移到最后
toIndex = lastWidgetIndex;
else
{
for (int i = 0; i < count(); ++i)
{
CustomTab* dropTab = tab(i);
if(!dropTab)
continue;
QRect tabGeometry = dropTab->geometry();
if( !tabGeometry.contains(event->position().toPoint()) )
continue;
toIndex = m_pTabsLayout->indexOf(dropTab);
if(toIndex > 0 && m_pPosMarking->isVisible())
{
int nIndex = toIndex - 1;
if(m_pTabsLayout->indexOf(m_pPosMarking) == nIndex)//判断上一帧是否已经将posMarking放入到该tab之前
toIndex = -1;
else if(m_pTabsLayout->indexOf(m_pPosMarking) < toIndex)//在dropTab之前插入了posMarking会让dropTab的索引放生变化+1
toIndex -= 1;
}
break;
}
}
qDebug() << toIndex;
if(toIndex != -1)
{
m_pPosMarking->show();
m_pTabsLayout->insertWidget(toIndex, m_pPosMarking);
}
}
void CustomTabBar::dragLeaveEvent(QDragLeaveEvent* event)
{
qDebug() << "dragLeaveEvent";
}
void CustomTabBar::dropEvent(QDropEvent* event)
{
//qDebug() << "dropEvent";
int toIndex = m_pTabsLayout->indexOf(m_pPosMarking);
m_pPosMarking->hide();
m_pTabsLayout->removeWidget(m_pPosMarking);
CustomTab* sourceObj = qobject_cast<CustomTab*>(event->source());
if(!sourceObj)
return;
int fromIndex = m_pTabsLayout->indexOf(sourceObj);
if(toIndex > fromIndex)//因为被移动的tab要先remove出来再insert如果是向后移动remove会引起索引的变化所以要-1
toIndex -= 1;
if(toIndex != fromIndex) //移动
{
m_pTabsLayout->removeWidget(sourceObj);
m_pTabsLayout->insertWidget(toIndex, sourceObj);
emit tabMoved(fromIndex, toIndex);
}
qDebug() << fromIndex << toIndex;
}
int CustomTabBar::count()
{
//含有一个stretch
return m_pTabsLayout->count() - 1;
}
/*void CustomTabBar::insertTab(int index, CustomTab* tab)
{
if(index < 0)
index = 0;
else if(index > count())
index = count();
m_pTabsLayout->insertWidget(index, tab);
ensureWidgetVisible(tab); //定位到可以显示该tab
m_nCurrentIndex = index;
}*/
void CustomTabBar::addTab(CustomTab* tab)
{
m_pTabsLayout->insertWidget(count(), tab);
ensureWidgetVisible(tab); //定位到可以显示该tab
tab->setTabBar(objectName());
}
void CustomTabBar::removeTab(CustomTab* tab)
{
m_pTabsLayout->removeWidget(tab);
}
CustomTab* CustomTabBar::tab(int index)
{
if (index >= count() || index < 0)
{
return nullptr;
}
return qobject_cast<CustomTab*>(m_pTabsLayout->itemAt(index)->widget());
}
void CustomTabBar::onTabClicked()
{
}

View File

@ -1,5 +1,6 @@
#include "dashboard.h" #include "dashboard.h"
#include "dataPanel.h" #include "dataPanel.h"
#include "customTab.h"
#include <QDialog> #include <QDialog>
#include <QPushButton> #include <QPushButton>
@ -14,20 +15,15 @@ Dashboard::Dashboard(const QString& strName, QObject *parent)
//displayArea //displayArea
m_pDisplayArea = new QWidget(); m_pDisplayArea = new QWidget();
m_pDisplayArea->setObjectName("displayArea"); m_pDisplayArea->setObjectName("displayArea");
m_pDisplayAreaLayout = nullptr;
//m_pDisplayArea->setStyleSheet("QWidget #displayArea {background-color: rgb(18, 25, 30);}"); //m_pDisplayArea->setStyleSheet("QWidget #displayArea {background-color: rgb(18, 25, 30);}");
//tabButton,自适应text内容 //tab,自适应text内容
m_pTabButton = new QPushButton(); m_pTab = new CustomTab();
m_pTabButton->setContextMenuPolicy(Qt::CustomContextMenu); //m_pTabButton->setIcon(QIcon(":/images/btn_float_default.png"));
m_pTabButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); connect(m_pTab, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(contextMenu_tab(const QPoint&)));
m_pTabButton->setStyleSheet("QPushButton{\n"
" font:600 11pt \"微软雅黑\";\n"
" padding-left:5px;\n"
" padding-right:5px;\n"
"}\n");
connect(m_pTabButton, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(contextMenu_tabButton(const QPoint&)));
//右键菜单 //右键菜单
m_pTabBtnMenu = new QMenu(); m_pTabMenu = new QMenu();
m_pTabBtnMenu->setStyleSheet("QMenu{\n" m_pTabMenu->setStyleSheet("QMenu{\n"
" background-color:rgb(36,43,50);\n" " background-color:rgb(36,43,50);\n"
" border:1px solid rgb(6, 6, 6);\n" " border:1px solid rgb(6, 6, 6);\n"
"}\n" "}\n"
@ -41,8 +37,8 @@ Dashboard::Dashboard(const QString& strName, QObject *parent)
"QMenu:item:selected{\n" "QMenu:item:selected{\n"
" background-color: rgba(67,160,249, 80);\n" " background-color: rgba(67,160,249, 80);\n"
"}\n"); "}\n");
m_pTabBtnMenu->addAction(QString::fromWCharArray(L"删除"), this, SLOT(onAction_remove())); m_pTabMenu->addAction(QString::fromWCharArray(L"删除"), this, SLOT(onAction_remove()));
m_pTabBtnMenu->addAction(QString::fromWCharArray(L"重命名"), this, SLOT(onAction_rename())); m_pTabMenu->addAction(QString::fromWCharArray(L"重命名"), this, SLOT(onAction_rename()));
m_nPanenlNameNumber = 0; m_nPanenlNameNumber = 0;
@ -51,34 +47,27 @@ Dashboard::Dashboard(const QString& strName, QObject *parent)
Dashboard::~Dashboard() Dashboard::~Dashboard()
{ {
//m_pMdiArea和m_pTabButton不需要进行以下手动析构因为QObject建立起的父子结构会自动析构自动析构时不会将其置为nullptr所以if判断无效会引起'SIGSEGV'(存储器段错误)报错 //在这里m_pDisplayArea和m_pTabButton不需要进行手动析构因为QObject建立起的父子结构会自动析构自动析构时不会将其置为nullptr所以if判断无效会引起'SIGSEGV'(存储器段错误)报错
if(m_pTabBtnMenu) if(m_pTabMenu)
{ {
delete m_pTabBtnMenu; delete m_pTabMenu;
m_pTabBtnMenu = nullptr; m_pTabMenu = nullptr;
} }
} }
void Dashboard::updateTabButtonSize() void Dashboard::deleteSubWidgets()
{ {
QFontMetrics metrics(m_pTabButton->font()); if(m_pTab)
QRect rect = metrics.boundingRect(m_pTabButton->text());
m_pTabButton->setMinimumSize(rect.width() + 30, tabButtonHeight);
m_pTabButton->setMaximumSize(rect.width() + 30, tabButtonHeight);
/*int nWidth = 0;
for(int n=0; n<strName.size(); n++)
{ {
QChar c = strName.at(n); delete m_pTab;
ushort uni = c.unicode(); m_pTab = nullptr;
if(uni >= 0x4E00 && uni <= 0x9FA5) //为汉字 }
nWidth += 12;
else if(m_pDisplayArea)
nWidth += 7; {
delete m_pDisplayArea;
m_pDisplayArea = nullptr;
} }
nWidth += 35;
m_pTabButton->setMinimumSize(nWidth, tabButtonHeight);
m_pTabButton->setMaximumSize(nWidth, tabButtonHeight);*/
} }
const QString& Dashboard::getName() const QString& Dashboard::getName()
@ -88,13 +77,17 @@ const QString& Dashboard::getName()
void Dashboard::setName(const QString& strName) void Dashboard::setName(const QString& strName)
{ {
m_strName = strName; m_strName = strName;
m_pTabButton->setText(strName); m_pTab->setText(strName);
updateTabButtonSize();
} }
QPushButton* Dashboard::tabButton() void Dashboard::setDisplayAreaLayout(QHBoxLayout* pLayout)
{ {
return m_pTabButton; m_pDisplayAreaLayout = pLayout;
}
CustomTab* Dashboard::tab()
{
return m_pTab;
} }
QWidget* Dashboard::displayArea() QWidget* Dashboard::displayArea()
@ -102,30 +95,20 @@ QWidget* Dashboard::displayArea()
return m_pDisplayArea; return m_pDisplayArea;
} }
void Dashboard::setSelected(bool bSelected) void Dashboard::setActive(bool bActive)
{ {
QString strStyleSheet = ""; if(bActive && m_pDisplayAreaLayout)
if(bSelected) {
strStyleSheet = "QPushButton{\n" m_pDisplayAreaLayout->addWidget(m_pDisplayArea);
" color:rgb(250,250,250);\n" m_pDisplayArea->show();
" font:600 11pt \"微软雅黑\";\n" }
" border-bottom:3px solid rgb(67,160,249);\n" else if(!bActive && m_pDisplayAreaLayout)
"}\n" {
"QPushButton:hover{\n" m_pDisplayAreaLayout->removeWidget(m_pDisplayArea);
" background-color: rgba(60, 60, 60, 150);\n" m_pDisplayArea->hide();
"}\n"; }
else
strStyleSheet = "QPushButton{\n"
" color:rgb(220,220,220);\n"
" font:11pt \"微软雅黑\";\n"
" border-bottom:0px;\n"
"}\n"
"QPushButton:hover{\n"
" background-color: rgba(60, 60, 60, 150);\n"
"}\n";
m_pTabButton->setStyleSheet(strStyleSheet); m_pTab->setActive(bActive);
updateTabButtonSize();
} }
void Dashboard::addPanel(const QString& strType) void Dashboard::addPanel(const QString& strType)
@ -164,10 +147,10 @@ void Dashboard::removePanel(const QString& strName)
} }
} }
void Dashboard::contextMenu_tabButton(const QPoint& pos) void Dashboard::contextMenu_tab(const QPoint& pos)
{ {
QPoint originPoint = m_pTabButton->mapToGlobal(QPoint(0, 0)); QPoint originPoint = m_pTab->mapToGlobal(QPoint(0, 0));
m_pTabBtnMenu->popup(originPoint + pos); m_pTabMenu->popup(originPoint + pos);
} }
void Dashboard::onAction_remove() void Dashboard::onAction_remove()

View File

@ -2,7 +2,9 @@
#include "./ui_dvieMainWindow.h" #include "./ui_dvieMainWindow.h"
#include "transparentMask.h" #include "transparentMask.h"
#include "messageDialog.h" #include "messageDialog.h"
#include "customTabBar.h"
#include "dashboard.h" #include "dashboard.h"
#include "customTab.h"
#include "dashboardNamingDialog.h" #include "dashboardNamingDialog.h"
#include "panelSelectionDialog.h" #include "panelSelectionDialog.h"
#include "dateTimeWidget.h" #include "dateTimeWidget.h"
@ -10,14 +12,17 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QMenu> #include <QMenu>
#include <QDateTime> #include <QDateTime>
#include <QDrag>
#include <QMimeData>
DvieMainWindow::DvieMainWindow(QWidget *parent) DvieMainWindow::DvieMainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::dvieMainWindow) , ui(new Ui::dvieMainWindow)
, m_pTransparentMask(nullptr) , m_pTransparentMask(nullptr)
, m_pMessageDialog(nullptr) , m_pMessageDialog(nullptr)
, m_pDashboardTabBar(nullptr)
, m_pDashboardNamingDialog(nullptr) , m_pDashboardNamingDialog(nullptr)
, m_curSelectedDashboard(nullptr) , m_curActiveDashboard(nullptr)
, m_curOperationDashboard(nullptr) , m_curOperationDashboard(nullptr)
, m_pPanelSelectionDialog(nullptr) , m_pPanelSelectionDialog(nullptr)
{ {
@ -29,6 +34,11 @@ DvieMainWindow::DvieMainWindow(QWidget *parent)
connect(m_pDateTimeWidget, SIGNAL(hideMask()), this, SLOT(onSignal_hideMask())); connect(m_pDateTimeWidget, SIGNAL(hideMask()), this, SLOT(onSignal_hideMask()));
connect(m_pDateTimeWidget, SIGNAL(viewHistoricalData(QDateTime)), this, SLOT(onSignal_viewHistoricalData(QDateTime))); connect(m_pDateTimeWidget, SIGNAL(viewHistoricalData(QDateTime)), this, SLOT(onSignal_viewHistoricalData(QDateTime)));
m_pDashboardTabBar = new CustomTabBar(this);
m_pDashboardTabBar->setObjectName("mainWindow_Bar");
ui->hLayout_dashboardTabBar->addWidget(m_pDashboardTabBar);
connect(m_pDashboardTabBar, SIGNAL(tabMoved(int, int)), this, SLOT(onSignal_dashboardTabMoved(int, int)));
connect(ui->btnAddDashboard, SIGNAL(clicked()), this, SLOT(onBtnClicked_addDashboard())); connect(ui->btnAddDashboard, SIGNAL(clicked()), this, SLOT(onBtnClicked_addDashboard()));
connect(ui->btnAddPanel, SIGNAL(clicked()), this, SLOT(onBtnClicked_addDataPanel())); connect(ui->btnAddPanel, SIGNAL(clicked()), this, SLOT(onBtnClicked_addDataPanel()));
//connect(ui->btnDashboradList1, SIGNAL(clicked()), this, SLOT(onBtnClicked_dashboardList())); //connect(ui->btnDashboradList1, SIGNAL(clicked()), this, SLOT(onBtnClicked_dashboardList()));
@ -95,34 +105,70 @@ void DvieMainWindow::showMessageDialog(MessageDialogType type,const QString& str
m_pMessageDialog->show(); m_pMessageDialog->show();
} }
void DvieMainWindow::addADashboard(const QString& strName) void DvieMainWindow::addDashboard(const QString& strName)
{ {
Dashboard* dashboard = new Dashboard(strName, this); Dashboard* dashboard = new Dashboard(strName, this);
connect(dashboard, SIGNAL(sgl_rename()), this, SLOT(onSignal_renameDashboard())); connect(dashboard, SIGNAL(sgl_rename()), this, SLOT(onSignal_renameDashboard()));
connect(dashboard, SIGNAL(sgl_remove()), this, SLOT(onSignal_removeDashboard())); connect(dashboard, SIGNAL(sgl_remove()), this, SLOT(onSignal_removeDashboard()));
dashboard->setDisplayAreaLayout(ui->hLayout_dashboardDisplayArea);
QPushButton* tabButton = dashboard->tabButton(); //添加tab
QWidget* displayArea = dashboard->displayArea(); CustomTab* tab = dashboard->tab();
//添加tabButton m_pDashboardTabBar->addTab(tab);
int nCount = m_listDashboard.count(); connect(tab, SIGNAL(clicked()), this, SLOT(onBtnClicked_dashboardTab()));
ui->hLayout_dashboardTab->insertWidget(nCount,tabButton); //已经内置好了一个水平spacer所以要放置在其之前
connect(tabButton, SIGNAL(clicked()), this, SLOT(onBtnClicked_dashboardTab()));
//添加mdiArea
QWidget* page = new QWidget(ui->dashboardStack);
QString objName = "page_dashboard_" + strName;
page->setObjectName(objName);
ui->dashboardStack->addWidget(page);
QHBoxLayout* pageLayout = new QHBoxLayout(page);
pageLayout->setContentsMargins(0, 0, 0, 0);
pageLayout->addWidget(displayArea);
displayArea->setParent(page);
ui->dashboardStack->setCurrentWidget(page);
m_listDashboard.push_back(dashboard); m_listDashboard.push_back(dashboard);
dashboard->setSelected(true); if(m_curActiveDashboard)
if(m_curSelectedDashboard) m_curActiveDashboard->setActive(false);
m_curSelectedDashboard->setSelected(false); dashboard->setActive(true);
m_curSelectedDashboard = dashboard; m_curActiveDashboard = dashboard;
}
void DvieMainWindow::removeDashboard(const QString& strName, bool bDelete) //右键删除和移动到别的frame下均会调用该函数只有删除时才会delete
{
int nIndex = 0;
Dashboard* dashboard = nullptr;
for(int n=0; n<m_listDashboard.count(); n++)
{
if(m_listDashboard.at(n)->getName() == strName)
{
nIndex = n;
dashboard = m_listDashboard.at(n);
break;
}
}
if( !dashboard )
return;
if(dashboard == m_curActiveDashboard) //删除的是当前所选
{
dashboard->setActive(false);
if(m_listDashboard.count() == 1) //唯一一个
m_curActiveDashboard = nullptr;
else
{
if(nIndex != 0) //不是第一个,将其前一个置为选中状态
{
m_listDashboard.at(nIndex - 1)->setActive(true);
m_curActiveDashboard = m_listDashboard.at(nIndex - 1);
}
else //是第一个,将下一个置为选中状态
{
m_listDashboard.at(nIndex + 1)->setActive(true);
m_curActiveDashboard = m_listDashboard.at(nIndex + 1);
}
}
}
CustomTab* tab = dashboard->tab();
if(tab)
m_pDashboardTabBar->removeTab(tab);
m_listDashboard.removeAt(nIndex);
if(bDelete)
{
dashboard->deleteSubWidgets();
delete dashboard;
}
} }
void DvieMainWindow::setCurrentDashboard(const QString& strName) void DvieMainWindow::setCurrentDashboard(const QString& strName)
@ -131,13 +177,14 @@ void DvieMainWindow::setCurrentDashboard(const QString& strName)
{ {
if(m_listDashboard.at(n)->getName() == strName) if(m_listDashboard.at(n)->getName() == strName)
{ {
if(m_listDashboard.at(n) == m_curSelectedDashboard) if(m_listDashboard.at(n) == m_curActiveDashboard)
return; return;
ui->dashboardStack->setCurrentIndex(n); m_curActiveDashboard->setActive(false);
m_listDashboard.at(n)->setSelected(true); m_listDashboard.at(n)->setActive(true);
m_curSelectedDashboard->setSelected(false); CustomTab* tab = m_listDashboard.at(n)->tab();
m_curSelectedDashboard = m_listDashboard.at(n); m_pDashboardTabBar->ensureWidgetVisible(tab);
m_curActiveDashboard = m_listDashboard.at(n);
} }
} }
} }
@ -231,7 +278,7 @@ void DvieMainWindow::onBtnClicked_dashboardList()
void DvieMainWindow::onBtnClicked_dashboardTab() void DvieMainWindow::onBtnClicked_dashboardTab()
{ {
QPushButton* pBtn = qobject_cast<QPushButton*>(sender()); CustomTab* pBtn = qobject_cast<CustomTab*>(sender());
QString strName = pBtn->text(); QString strName = pBtn->text();
setCurrentDashboard(strName); setCurrentDashboard(strName);
} }
@ -261,65 +308,33 @@ void DvieMainWindow::onSignal_dashboardNaming(const QString& strName, const QStr
} }
if(strUsedFor == "create") if(strUsedFor == "create")
addADashboard(strName); addDashboard(strName);
else if(strUsedFor == "rename" && m_curOperationDashboard) else if(strUsedFor == "rename" && m_curOperationDashboard)
m_curOperationDashboard->setName(strName); m_curOperationDashboard->setName(strName);
m_pDashboardNamingDialog->hide(); m_pDashboardNamingDialog->hide();
hideTransparentMask(); hideTransparentMask();
} }
void DvieMainWindow::onSignal_dashboardTabMoved(int nFromIndex, int nToIndex)
{
//同步相应数据在其存储接结构中的位置
Dashboard* movingDashboard = m_listDashboard.takeAt(nFromIndex);
m_listDashboard.insert(nToIndex, movingDashboard);
}
void DvieMainWindow::onSignal_removeDashboard() void DvieMainWindow::onSignal_removeDashboard()
{ {
m_curOperationDashboard = qobject_cast<Dashboard*>(sender()); Dashboard* dashboard = qobject_cast<Dashboard*>(sender());
if(m_curOperationDashboard) if(dashboard)
{ {
showTransparentMask(); showTransparentMask();
QString strName = m_curOperationDashboard->getName(); QString strName = dashboard->getName();
QString strMsg = QString::fromStdWString(L"确认删除名为 \"") + strName + QString::fromStdWString(L"\" 的数据看板吗?"); QString strMsg = QString::fromStdWString(L"确认删除名为 \"") + strName + QString::fromStdWString(L"\" 的数据看板吗?");
showMessageDialog(type_question, QString::fromStdWString(L"删除看板"), strMsg); showMessageDialog(type_question, QString::fromStdWString(L"删除看板"), strMsg);
if(g_msgDlgBtn == btn_No) if(g_msgDlgBtn == btn_No)
return; return;
removeDashboard(strName, true);
QPushButton* tabButton = m_curOperationDashboard->tabButton();
QWidget* displayArea = m_curOperationDashboard->displayArea();
if(tabButton)
{
ui->dashboardStack->removeWidget(tabButton);
delete tabButton;
}
if(displayArea)
{
QWidget* page = displayArea->parentWidget();
if(page)
{
ui->dashboardStack->removeWidget(page);
delete page;
}
}
int nIndex = 0;
for(int n=0; n<m_listDashboard.count(); n++)
{
if(m_listDashboard.at(n) == m_curOperationDashboard)
{
nIndex = n;
break;
}
}
if(m_curOperationDashboard == m_curSelectedDashboard) //如果删除的是当前选中且不是第一个,将其前一个置为选中状态
{
if(nIndex != 0)
{
m_curSelectedDashboard = m_listDashboard.at(nIndex - 1);
m_curSelectedDashboard->setSelected(true);
}
else
m_curSelectedDashboard = nullptr;
}
m_listDashboard.removeAt(nIndex);
delete m_curOperationDashboard;
m_curOperationDashboard = nullptr;
} }
} }
@ -346,7 +361,7 @@ void DvieMainWindow::onSignal_panelSelectResult(const QString& strType)
{ {
//m_pPanelSelectionDialog->hide(); //m_pPanelSelectionDialog->hide();
hideTransparentMask(); hideTransparentMask();
m_curSelectedDashboard->addPanel(strType); m_curActiveDashboard->addPanel(strType);
} }
void DvieMainWindow::onSignal_viewHistoricalData(QDateTime dateTime) void DvieMainWindow::onSignal_viewHistoricalData(QDateTime dateTime)

View File

@ -179,7 +179,7 @@ font: 700 12pt &quot;微软雅黑&quot;;</string>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Orientation::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
@ -263,7 +263,7 @@ font: 10pt &quot;微软雅黑&quot;;</string>
<string>TakeCare1987</string> <string>TakeCare1987</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="btnTheme"> <widget class="QPushButton" name="btnTheme">
@ -334,7 +334,7 @@ QPushButton:pressed
</size> </size>
</property> </property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">background-color: rgba(39, 102, 59, 200);</string> <string notr="true">background-color: rgba(0, 141, 212, 80);</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -630,7 +630,7 @@ border-bottom:0px;</string>
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="page_dashboard"> <widget class="QWidget" name="page_dashboard">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="hLayout_dashboardTabBar">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -725,63 +725,6 @@ QPushButton:pressed
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QScrollArea" name="dashboardTabArea">
<property name="styleSheet">
<string notr="true">border:0px;
background-color:transparent;</string>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1188</width>
<height>50</height>
</rect>
</property>
<layout class="QHBoxLayout" name="hLayout_dashboardTab">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="hSpacer_dashboradTab">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="page_notification"/> <widget class="QWidget" name="page_notification"/>
@ -870,7 +813,7 @@ QPushButton:pressed
<string notr="true"/> <string notr="true"/>
</property> </property>
<widget class="QWidget" name="page_dashboards"> <widget class="QWidget" name="page_dashboards">
<layout class="QHBoxLayout" name="hLayoutpageDashboards"> <layout class="QHBoxLayout" name="hLayout_dashboardDisplayArea">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
</property> </property>
@ -886,9 +829,6 @@ QPushButton:pressed
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<widget class="QStackedWidget" name="dashboardStack"/>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="page_notifications"/> <widget class="QWidget" name="page_notifications"/>
@ -897,6 +837,8 @@ QPushButton:pressed
</layout> </layout>
</widget> </widget>
</widget> </widget>
<resources/> <resources>
<include location="../resource/PowerMaster.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>