使用 for Qt 制作无边框窗口
Posted
技术标签:
【中文标题】使用 for Qt 制作无边框窗口【英文标题】:Making a borderless window with for Qt 【发布时间】:2011-01-15 04:12:24 【问题描述】:我是 Qt C++ 的新手。我下载了最新的 windows 版本,做了一些教程,非常棒。
我看到了 Qt 框架具有的一些样式选项,并且非常棒,但现在我需要构建我的应用程序,它的主窗口(窗体)用没有矩形边框(无边框?)的图像设计/蒙皮。
我怎样才能用 Qt 做到这一点?
【问题讨论】:
【参考方案1】:如果您正在寻找一些小部件形状的高级样式,也许这个示例会对您有所帮助:
Shaped Clock Example
或者您可能只是在寻找这种标志:Qt::CustomizeWindowHint
或只是 Qt::FramelessWindowHint
。
【讨论】:
异形时钟的例子就是这样,还有像这样的例子吗? 代码如下:Qt::WindowFlags flags = this->windowFlags(); this->setWindowFlags(flags|Qt::FramelessWindowHint);【参考方案2】:我创建了一个小例子,说明如何在 Qt5 中创建类似 VS2013 的无框窗口:
您可以在这里获得完整的来源:https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle
否则这里是如何将“主”主窗口嵌入“无框架”窗口的代码概述。您还可以了解如何添加标题栏、按钮以及如何最大化、调整和移动无框窗口。
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
/*
place your QMainWindow code here
*/
namespace Ui
class MainWindow;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
;
/*
this class is to add frameless window supoort and do all the stuff with titlebar and buttons
*/
class BorderlessMainWindow: public QMainWindow
Q_OBJECT
public:
explicit BorderlessMainWindow(QWidget *parent = 0);
~BorderlessMainWindow()
protected:
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent *event);
private slots:
void slot_minimized();
void slot_restored();
void slot_maximized();
void slot_closed();
private:
MainWindow *mMainWindow;
QWidget *mTitlebarWidget;
QLabel *mWindowTitle;
QPushButton *mMinimizeButton;
QPushButton *mRestoreButton;
QPushButton *mMaximizeButton;
QPushButton *mCloseButton;
QPoint mLastMousePosition;
bool mMoving;
bool mMaximized;
;
#endif // MAINWINDOW_H
主窗口.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
/*
frameless window class: it adds the MainWindow class inside the centralWidget
*/
BorderlessMainWindow::BorderlessMainWindow(QWidget *parent) : QMainWindow(parent, Qt::CustomizeWindowHint )
setObjectName("borderlessMainWindow");
setWindowFlags(Qt::FramelessWindowHint| Qt::WindowSystemMenuHint);
// to fix taskbar minimize feature
setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint);
mMainWindow = new MainWindow(this);
setWindowTitle(mMainWindow->windowTitle());
QVBoxLayout *verticalLayout = new QVBoxLayout();
verticalLayout->setSpacing(0);
verticalLayout->setMargin(1);
QHBoxLayout *horizontalLayout = new QHBoxLayout();
horizontalLayout->setSpacing(0);
horizontalLayout->setMargin(0);
mTitlebarWidget = new QWidget(this);
mTitlebarWidget->setObjectName("titlebarWidget");
mTitlebarWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
mTitlebarWidget->setLayout(horizontalLayout);
mMinimizeButton = new QPushButton(mTitlebarWidget);
mMinimizeButton->setObjectName("minimizeButton");
connect(mMinimizeButton, SIGNAL(clicked()), this, SLOT(slot_minimized()));
mRestoreButton = new QPushButton(mTitlebarWidget);
mRestoreButton->setObjectName("restoreButton");
mRestoreButton->setVisible(false);
connect(mRestoreButton, SIGNAL(clicked()), this, SLOT(slot_restored()));
mMaximizeButton = new QPushButton(mTitlebarWidget);
mMaximizeButton->setObjectName("maximizeButton");
connect(mMaximizeButton, SIGNAL(clicked()), this, SLOT(slot_maximized()));
mCloseButton = new QPushButton(mTitlebarWidget);
mCloseButton->setObjectName("closeButton");
connect(mCloseButton, SIGNAL(clicked()), this, SLOT(slot_closed()));
mWindowTitle = new QLabel(mTitlebarWidget);
mWindowTitle->setObjectName("windowTitle");
mWindowTitle->setText(windowTitle());
horizontalLayout->addWidget(mWindowTitle);
horizontalLayout->addStretch(1);
horizontalLayout->addWidget(mMinimizeButton);
horizontalLayout->addWidget(mRestoreButton);
horizontalLayout->addWidget(mMaximizeButton);
horizontalLayout->addWidget(mCloseButton);
verticalLayout->addWidget(mTitlebarWidget);
verticalLayout->addWidget(mMainWindow);
QWidget *centralWidget = new QWidget(this);
centralWidget->setObjectName("centralWidget");
centralWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
centralWidget->setLayout(verticalLayout);
setCentralWidget(centralWidget);
void BorderlessMainWindow::mousePressEvent(QMouseEvent* event)
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
if(event->button() == Qt::LeftButton)
mMoving = true;
mLastMousePosition = event->pos();
void BorderlessMainWindow::mouseMoveEvent(QMouseEvent* event)
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
if( event->buttons().testFlag(Qt::LeftButton) && mMoving)
this->move(this->pos() + (event->pos() - mLastMousePosition));
void BorderlessMainWindow::mouseReleaseEvent(QMouseEvent* event)
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
if(event->button() == Qt::LeftButton)
mMoving = false;
void BorderlessMainWindow::mouseDoubleClickEvent(QMouseEvent *event)
Q_UNUSED(event);
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
mMaximized = !mMaximized;
if (mMaximized)
slot_maximized();
else
slot_restored();
void BorderlessMainWindow::slot_minimized()
setWindowState(Qt::WindowMinimized);
void BorderlessMainWindow::slot_restored()
mRestoreButton->setVisible(false);
mMaximizeButton->setVisible(true);
setWindowState(Qt::WindowNoState);
setStyleSheet("#borderlessMainWindowborder:1px solid palette(highlight);");
void BorderlessMainWindow::slot_maximized()
mRestoreButton->setVisible(true);
mMaximizeButton->setVisible(false);
setWindowState(Qt::WindowMaximized);
setStyleSheet("#borderlessMainWindowborder:1px solid palette(base);");
void BorderlessMainWindow::slot_closed()
close();
/*
MainWindow class: put all your code here
*/
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent, Qt::FramelessWindowHint), ui(new Ui::MainWindow)
ui->setupUi(this);
statusBar()->setSizeGripEnabled(true);
MainWindow::~MainWindow()
delete ui;
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。请阅读此how-to-answer 以提供高质量的答案。【参考方案3】:在您的 Qt 目录中有一个示例应用程序:examples/widgets/windowsflags
。
【讨论】:
【参考方案4】:我自己遇到了这个问题,过了一段时间才弄清楚。查看https://github.com/ianbannerman/TrueFramelessWindow 以获取适用于 Windows 和 macOS 的示例代码。
Qt::FramelessWindowHint 牺牲了调整大小和最小/最大/关闭,所以可能不是大多数人想要的。
【讨论】:
读者注意:您仍然可以自己处理最小/最大/关闭/调整大小/拖动操作。它需要额外的代码,但这是可能的。我有一个不错的无框应用程序,它带有我自己的自定义标题栏,它的作用就像一个真实的窗口。 @JohnDoe 您的代码是否也可以在 linux 上运行?抱歉在这里问,但我开始变得绝望;)以上是关于使用 for Qt 制作无边框窗口的主要内容,如果未能解决你的问题,请参考以下文章