geometry()、frameGeometry()、pos()、size()、rect()的区别

QWidget为单独的窗口展示

QWidget的这几个方法都与窗口的几何信息有关,作为单独的窗口展示时,我们来看一下他们的一些区别

  • geometry():获取的矩形不包括窗口自带的标题栏,只包括窗口的内容区
  • frameGeometry():获取的矩形为整个窗口的矩形,包含自带的标题栏和内容区(如果因为自定义标题栏而去掉了自带的标题栏,那么获取的矩形就和geometry()一样)
  • pos():获取的位置为整个窗口的左上角在屏幕中的位置,包含标题栏(如果因为自定义标题栏而去掉了自带的标题栏,那么pos的位置就和geometry()获取的矩形的左上角一致)
  • size():大小和geometry()获取的矩形一样,即内容区的size
  • rect():获取的矩形大小和geometry()获取的矩形一样,只不过左上角永远是(0,0),rect()不包含位置信息,只包含了宽高信息
  • width():和geometry()获取的矩形的宽度一样,即内容区的宽度
  • height():和geometry()获取的矩形的高度一样,即内容区的高度

dd1c4e2b89d9423a9633273e48a8f66f.png

QWidget内嵌显示

内嵌显示的时候:其他几个方法都和geometry()没有区别,pos获取的是在父窗口中的位置,而不是在整个屏幕的位置

学习链接:https://github.com/0voice 

 

#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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值