QML自定义控件之退出对话框

QML自定义控件之退出对话框

1、效果

自定义退出对话框效果

2、代码

import QtQuick 2.0
import QtQuick.Controls 2.14

Rectangle {
    width: 420
    height: 190
    radius: 10
    color: "#B0BDEA"

    property color quitnormalColor: "#0E5FAA"
    //"14,95,170" 设置#值透明度:每个值除以255
    property color quithoveredColor: Qt.rgba(14/255,95/255,170/255, 0.9) 

    property color normalColor: "#FFFFFF"
    property color textnormalColor: "#000000"
    property color hoveredColor: "#FFFFFF"
    property color pressedColor: "#BBB3B3"
    property color releaseColor: "#FFFFFF"

    Text {
        id: quitMaxText
        x: 15
        y: 22
        font.family: "黑体"
        font.pixelSize: 40
        font.bold: true

        text: qsTr("退出")
    }

    Text {
        id: infor
        x: 15
        y: 86
        font.family: "黑体"
        font.pixelSize: 16
        text: qsTr("确定要退出程序吗?")
    }

    Rectangle {
        id:cancle
        x:15
        y:136
        width: 110
        height: 35
        radius: 5
        Text {
            id: cancletext
            width: 60
            height: 15
            horizontalAlignment: Qt.AlignHCenter
            verticalAlignment: Qt.AlignVCenter
            x: (cancle.width-cancletext.width)/2
            y: (cancle.height-cancletext.height)/2
            font.pixelSize: 16
            font.family: "黑体"
            text: qsTr("取消")
        }
        MouseArea {
            anchors.fill: parent
            onClicked: {
                console.log(qsTr(cancletext.text))
            }

            onPressed: {
                cancletext.color = pressedColor
            }

            onReleased: {
                cancletext.color = textnormalColor
            }
        }
    }

    Rectangle {
        id:min
        x:145
        y:136
        width: 130
        height: 35
        radius: 5
        Text {
            id: mintext
            width: 60
            height: 15
            horizontalAlignment: Qt.AlignHCenter
            verticalAlignment: Qt.AlignVCenter
            x: (min.width-mintext.width)/2
            y: (min.height-mintext.height)/2
            font.pixelSize: 16
            font.family: "黑体"
            text: qsTr("最小化")

        }
        MouseArea {
            anchors.fill: parent
            onClicked: {
                console.log(qsTr(mintext.text))
            }

            onPressed: {
                mintext.color = pressedColor
            }

            onReleased: {
                console.log("释放")
                mintext.color = textnormalColor
            }

            onEntered: {
                console.log("悬浮")
            }

            onExited: {
                console.log("离开")
            }
        }
    }


    Rectangle {
        id: quit
        x:295
        y:136
        width: 110
        height: 35
        radius: 5
        color: "#0E5FAA"

        states: [
            State {
                name: "pressed"
                PropertyChanges {
                    target: quit
                    color: pressedColor

                }
            },

            State {
                name: "hovereded"
                PropertyChanges {
                    target: quit
                    color: hoveredColor

                }
            }
        ]
        Text {
            id: quittext
            width: 60
            height: 15
            horizontalAlignment: Qt.AlignHCenter
            verticalAlignment: Qt.AlignVCenter
            x: (quit.width-quittext.width)/2
            y: (quit.height-quittext.height)/2
            font.pixelSize: 16
            color: "#FFFFFF"
            text: qsTr("退出")
            font.family: "黑体"
        }
        MouseArea {
            anchors.fill: parent
            hoverEnabled: true
            onClicked: {
                console.log(qsTr(quittext.text))
            }
            onPressed: {
                quittext.color = pressedColor
            }

            onReleased: {
                console.log("释放")
                quit.color = quitnormalColor
                quittext.color = releaseColor
            }

            onEntered: {
                console.log("悬浮")
                quit.color = quithoveredColor
            }

            onExited: {
                console.log("离开")
                quit.color = quitnormalColor
            }

        }
    }
}

3、结论

通过用一个大的Rectangle作为弹窗,可以根据程序整体背景设置弹窗的背景颜色,也就是大Rectangle的背景
颜色;再通过使用3个小Rectangle来实现按钮的不同状态显示的效果。用过这样自定义的控件,可以使我们的
程序更加美观。合作联系方式QQ(786453398)
#include "pch.h" #include "mainwindow.h" #include <QMenuBar> #include <QToolBar> #include <QAction> #include <QMessageBox> #include <QApplication> #include <QPushButton> #include <QVBoxLayout> #include <QTranslator> #include <QDebug> #include <QDir> #include <QFile> #include <QColor> #include <QHBoxLayout> #include <QSplitter> #include <QFileSystemModel> #include <QSizePolicy> #include <QDockWidget> #include <QStatusBar> #include <QButtonGroup> #include <QRadioButton> #include <QSpacerItem> #include <QPlainTextEdit> #include <QTimer> #include <QHoverEvent> #include <QMouseEvent> #include "2dRadialWidget.h" #include "baseItem.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), translator(new QTranslator(this)), isPress(false), mainWidget(new QWidget(this)), titleBar(new TitleBar(this)), log(new MainLogWidget(this)), stackedWidget(new QStackedWidget(this)), viewSwitch(new ViewSwitch(this)), //simulationWidget(new MainSimulationWidget(this)), psfWidget(new MainPSFWidget(this)), library(new MainLibraryWidget(this)), configurationWidget(new MainConfigurationWidget(this)), m_simulationAreaWidget(new SimulationArea(this)) { qDebug() << "Maximum resolution: " << this->maximumSize(); qDebug() << "Minimum resolution: " << this->minimumSize(); //setWindowFlags(Qt::FramelessWindowHint); // 隐藏系统标题栏 setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint); statusBar()->hide(); // 隐藏状态栏 setMinimumSize(800, 600); // 设置最小为 1920 * 1080 resize(1920, 1080); // 设置默认为 1920 * 1080 this->setContentsMargins(0, 0, 0, 0); // 创建缩放按钮 resizeButton = new QPushButton(mainWidget); resizeButton->setObjectName("resizeButton"); resizeButton->setFixedSize(40, 40); resizeButton->setStyleSheet( "QPushButton#resizeButton {" " border: none;" " background-color: transparent;" " image: url(:/resources/icons/icon_zoom.png);" "}" "QPushButton#resizeButton:hover {" " background-color: transparent;" "}" ); resizeButton->move(this->width() - resizeButton->width(), this->height() - resizeButton->height()); resizeButton->raise(); // 确保按钮在最上层 resizeButton->installEventFilter(this); // 安装事件过滤器 initTitleBar(); initLog(); initView(); initViewSwitch(); initLanguage(); initConnects(); //QVBoxLayout* mainLayout = new QVBoxLayout(this); QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget); mainLayout->setSpacing(0); mainLayout->setContentsMargins(0, 0, 0, 0); /* mainWidget->setLayout(mainLayout); mainWidget->setContentsMargins(0, 0, 0, 0);*/ setCentralWidget(mainWidget); // 添加布局 mainLayout->setContentsMargins(0, 0, 0, 0); // 设置内容边距,左上右下 mainLayout->addWidget(titleBar); mainLayout->addSpacing(5); mainLayout->addWidget(log); mainLayout->addSpacing(5); mainLayout->addWidget(stackedWidget); mainLayout->addWidget(viewSwitch); mainLayout->setStretchFactor(titleBar, 40); mainLayout->setStretchFactor(log, 74); mainLayout->setStretchFactor(stackedWidget, 864); mainLayout->setStretchFactor(viewSwitch, 55); } void MainWindow::UpdateSimulationWidgetData(const std::vector<std::vector<double>>& data) { // simulationWidget->updateSimulationResults(data); } void MainWindow::UpdateSimulationWidget2DPlot(const std::vector<PSFItem*>& psfs) { // simulationWidget->UpdateRadial2DPlotResults(psfs); } void MainWindow::ItemActivated(BaseItem* pItem) { if (!pItem) { return; } if (stackedWidget->currentWidget() != m_simulationAreaWidget) { viewSwitch->ViewChange(ViewSwitch::ViewType::Simulation); //stackedWidget->setCurrentWidget(m_simulationAreaWidget); } if (dynamic_cast<SimulationItem*>(pItem) || dynamic_cast<Plot2DItem*>(pItem)) { m_simulationAreaWidget->SetDisplayType(SimulationArea::DisplayType::Simulation); } else if(dynamic_cast<PSFFitItem*>(pItem)) { m_simulationAreaWidget->SetDisplayType(SimulationArea::DisplayType::PsfFit); } else if (dynamic_cast<PSFConvolveItem*>(pItem)) { m_simulationAreaWidget->SetDisplayType(SimulationArea::DisplayType::PsfConvolve); } m_simulationAreaWidget->ActivateItem(pItem); } std::string MainWindow::GetVersion() { return "1.0"; } void MainWindow::initTitleBar() { setMenuWidget(titleBar); // 设置标题栏 } void MainWindow::initViewSwitch() {} void MainWindow::initLog() {} void MainWindow::initView() { //stackedWidget->addWidget(simulationWidget); stackedWidget->addWidget(m_simulationAreaWidget); stackedWidget->addWidget(psfWidget); stackedWidget->addWidget(library); stackedWidget->addWidget(configurationWidget); stackedWidget->setCurrentIndex(0); // 设置默认显示 MainSimulationWidget } void MainWindow::initConnects() { // 标题栏信号和槽 QObject::connect(titleBar, &CustomTitleBar::maximizeClicked, this, [this]() { if (isMaximized()) { showNormal(); } else { showMaximized(); } }); QObject::connect(titleBar, &CustomTitleBar::edgePressed, this, [this](QPoint globalPos) { QPoint localPos = this->mapFromGlobal(globalPos); QEvent::Type eventType = QEvent::MouseMove; Qt::MouseButtons buttons = Qt::NoButton; static bool isFirstEvent = true; if (isFirstEvent) { eventType = QEvent::MouseButtonPress; buttons = Qt::LeftButton; isFirstEvent = false; } else { buttons = QApplication::mouseButtons(); } QMouseEvent* event = new QMouseEvent( eventType, localPos, Qt::LeftButton, buttons, Qt::NoModifier ); QApplication::postEvent(this, event); }); QObject::connect(titleBar, &CustomTitleBar::startMove, this, &MainWindow::onCustomTitleBarStartMove); QObject::connect(titleBar, &CustomTitleBar::moveWindow, this, &MainWindow::onCustomTitleBarMoveWindow); QObject::connect(titleBar, &CustomTitleBar::endMove, this, &MainWindow::onCustomTitleBarEndMove); // 视图切换信号和槽 connect(viewSwitch, &ViewSwitch::simulationButtonClicked, this, [this]() { stackedWidget->setCurrentIndex(0); }); connect(viewSwitch, &ViewSwitch::psfButtonClicked, this, [this]() { stackedWidget->setCurrentIndex(1); }); connect(viewSwitch, &ViewSwitch::libraryButtonClicked, this, [this]() { stackedWidget->setCurrentIndex(2); }); connect(viewSwitch, &ViewSwitch::configurationButtonClicked, this, [this]() { stackedWidget->setCurrentIndex(3); }); } void MainWindow::initLanguage() { QString language = ConfigManager::Instance().getLanguage(); translator = new QTranslator(this); if (language == "Chinese") { switchToChinese(); } else { switchToEnglish(); } } void MainWindow::switchToChinese() { qDebug() << "开始读取 zh_CN.qm"; auto result = translator->load(GlobalConstants::CHINESE_TRANSLATION); qApp->installTranslator(translator); retranslateUi(); } void MainWindow::switchToEnglish() { qDebug() << "开始读取 en_US.qm"; auto result = translator->load(GlobalConstants::ENGLISH_TRANSLATION); qApp->installTranslator(translator); retranslateUi(); } void MainWindow::retranslateUi() { viewSwitch->retranslateUi(); library->retranslateUi(); //simulationWidget->retranslateUi(); } void MainWindow::onCustomTitleBarStartMove(QPoint point) { isPress = true; } void MainWindow::onCustomTitleBarMoveWindow(QPoint point) { if (isPress) { this->move(point); } } void MainWindow::onCustomTitleBarEndMove() { isPress = false; } // 添加事件过滤器和resizeEvent处理 bool MainWindow::eventFilter(QObject* obj, QEvent* event) { if (obj == resizeButton) { QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); if (event->type() == QEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton) { // 开始拖动 m_dragStartPosition = mouseEvent->globalPos(); m_initialWindowGeometry = this->geometry(); resizeButton->grabMouse(); // 捕获鼠标 return true; } else if (event->type() == QEvent::MouseMove && (mouseEvent->buttons() & Qt::LeftButton)) { // 计算鼠标移动的偏移量 QPoint delta = mouseEvent->globalPos() - m_dragStartPosition; // 设置新窗口大小 QRect newGeometry = m_initialWindowGeometry; newGeometry.setWidth(m_initialWindowGeometry.width() + delta.x()); newGeometry.setHeight(m_initialWindowGeometry.height() + delta.y()); // 确保窗口不小于最小尺寸 if (newGeometry.width() >= minimumWidth() && newGeometry.height() >= minimumHeight()) { this->setGeometry(newGeometry); } return true; } else if (event->type() == QEvent::MouseButtonRelease && mouseEvent->button() == Qt::LeftButton) { resizeButton->releaseMouse(); return true; } } return QMainWindow::eventFilter(obj, event); } void MainWindow::resizeEvent(QResizeEvent* event) { QMainWindow::resizeEvent(event); // 保持按钮在右下角 if (resizeButton) { resizeButton->move(this->width() - resizeButton->width(), this->height() - resizeButton->height()); resizeButton->raise(); // 确保按钮始终在最上层 } } void MainWindow::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { m_dragPosition = event->globalPos() - frameGeometry().topLeft(); m_bResizing = false; QRect rect = this->rect(); QPoint pos = event->pos(); const int borderWidth = 8; // 检测是否在窗口边缘(用于调整大小) if (pos.y() <= borderWidth) { // +++ 上边框处理 +++ m_currentCorner = Top; m_bResizing = true; isPress = false; } else if (pos.x() <= borderWidth && pos.y() <= borderWidth) { m_currentCorner = TopLeft; m_bResizing = true; isPress = false; } else if (pos.x() >= rect.width() - borderWidth && pos.y() <= borderWidth) { m_currentCorner = TopRight; m_bResizing = true; isPress = false; } else if (pos.x() <= borderWidth && pos.y() >= rect.height() - borderWidth) { m_currentCorner = BottomLeft; m_bResizing = true; isPress = false; } else if (pos.x() >= rect.width() - borderWidth && pos.y() >= rect.height() - borderWidth) { m_currentCorner = BottomRight; m_bResizing = true; isPress = false; } else if (pos.x() <= borderWidth) { m_currentCorner = Left; m_bResizing = true; isPress = false; } else if (pos.x() >= rect.width() - borderWidth) { m_currentCorner = Right; m_bResizing = true; isPress = false; } else if (pos.y() >= rect.height() - borderWidth) { m_currentCorner = Bottom; m_bResizing = true; isPress = false; } else { // 正常拖动 m_currentCorner = None; m_bResizing = false; isPress = true; } event->accept(); } } void MainWindow::mouseMoveEvent(QMouseEvent* event) { if (m_bResizing) { // 调整窗口大小 QRect geometry = this->geometry(); switch (m_currentCorner) { case TopLeft: geometry.setTopLeft(event->globalPos()); break; case TopRight: geometry.setTopRight(event->globalPos()); break; case BottomLeft: geometry.setBottomLeft(event->globalPos()); break; case BottomRight: geometry.setBottomRight(event->globalPos()); break; case Left: geometry.setLeft(event->globalPos().x()); break; case Right: geometry.setRight(event->globalPos().x()); break; case Top: geometry.setTop(event->globalPos().y()); break; case Bottom: geometry.setBottom(event->globalPos().y()); break; default: break; } // 确保窗口不小于最小尺寸 if (geometry.width() >= minimumWidth() && geometry.height() >= minimumHeight()) { this->setGeometry(geometry); } event->accept(); } else if (isPress) { // 拖动窗口 move(event->globalPos() - m_dragPosition); event->accept(); } } void MainWindow::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { isPress = false; m_bResizing = false; // +++ 重置首次事件标志 +++ static bool isFirstEvent = true; isFirstEvent = true; event->accept(); } } void MainWindow::hoverMoveEvent(QHoverEvent* event) { QPoint pos = event->pos(); QRect rect = this->rect(); const int borderWidth = 8; // 检查是否在缩放按钮区域 if (resizeButton && resizeButton->geometry().contains(pos)) { setCursor(Qt::SizeFDiagCursor); event->accept(); return; } // +++ 检查是否在标题栏区域 +++ if (titleBar->geometry().contains(pos)) { // 在标题栏内,检查是否在上边框 if (pos.y() - titleBar->y() <= borderWidth) { setCursor(Qt::SizeVerCursor); event->accept(); return; } // 在标题栏非边框区域,使用箭头光标 setCursor(Qt::ArrowCursor); event->accept(); return; } // 其余边框的光标处理 if (pos.x() <= borderWidth && pos.y() <= borderWidth || pos.x() >= rect.width() - borderWidth && pos.y() >= rect.height() - borderWidth) { setCursor(Qt::SizeFDiagCursor); } else if (pos.x() >= rect.width() - borderWidth && pos.y() <= borderWidth || pos.x() <= borderWidth && pos.y() >= rect.height() - borderWidth) { setCursor(Qt::SizeBDiagCursor); } else if (pos.x() <= borderWidth || pos.x() >= rect.width() - borderWidth) { setCursor(Qt::SizeHorCursor); } else if (pos.y() <= borderWidth || pos.y() >= rect.height() - borderWidth) { setCursor(Qt::SizeVerCursor); } else { setCursor(Qt::ArrowCursor); } event->accept(); } // 启用鼠标悬停事件 bool MainWindow::event(QEvent* event) { if (event->type() == QEvent::HoverMove) { hoverMoveEvent(static_cast<QHoverEvent*>(event)); return true; } return QMainWindow::event(event); } 帮我搞懂这些
最新发布
06-25
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值