用Qt制作无边框窗口

发布于 2024-08-20 17:19:34 字数 155 浏览 7 评论 0原文

我是 Qt C++ 新手。我下载了最新的 Windows 版本,做了一些教程,非常棒。

我看到了 Qt 框架具有的一些样式选项,而且它很棒,但现在我需要构建我的应用程序,其主窗口(形式)是用没有矩形边框(无边框?)的图像设计/蒙皮的。

我怎样才能用Qt做到这一点?

I'm new to Qt C++. I downloaded the latest windows version, did some tutorials and its great.

I saw some styling options that the Qt framework has and its great, but now I need to build my application that its main windows (form) it designed/skinned with image without the rectangle borders (borderless?).

How can I do it with Qt?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

星星的轨迹 2024-08-27 17:19:34

如果您正在寻找小部件形状的一些高级样式,也许这个示例会对您有所帮助:

形状时钟示例

或者您可能只是在寻找这种标志:Qt::CustomizeWindowHint 或只是 Qt::FramelessWindowHint

If your looking for some advanced styling in the shape of a widget, maybe this example will help you:

Shaped Clock Example

Or maybe you're simply looking for this kind of flag: Qt::CustomizeWindowHint or simply Qt::FramelessWindowHint.

空袭的梦i 2024-08-27 17:19:34

我创建了一个小例子,说明如何在 Qt5 中创建类似 VS2013 的无框窗口: screenshot (mac) qt 深色风格无框窗口

您可以在这里获取完整的源代码:https ://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle

另外,这里是如何将“主”主窗口嵌入到“无框架”窗口中的代码概述。您还可以了解如何添加标题栏、按钮以及如何最大化、调整大小和移动无框窗口。

mainwindow.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

mainwindow.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("#borderlessMainWindow{border:1px solid palette(highlight);}");
}
void BorderlessMainWindow::slot_maximized() {
  mRestoreButton->setVisible(true);
  mMaximizeButton->setVisible(false);
  setWindowState(Qt::WindowMaximized);
  setStyleSheet("#borderlessMainWindow{border: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;
}

I created a small example, of how to create VS2013 like frameless window in Qt5: screenshot (mac) qt frameless window with dark style

You can get the complete sources here: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle

Otherwise here a code overview of how to embed the "main" mainwindow into the "frameless" window. Also you can see how to add titlebar, buttons and do maximize, resize and move of the frameless window.

mainwindow.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

mainwindow.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("#borderlessMainWindow{border:1px solid palette(highlight);}");
}
void BorderlessMainWindow::slot_maximized() {
  mRestoreButton->setVisible(true);
  mMaximizeButton->setVisible(false);
  setWindowState(Qt::WindowMaximized);
  setStyleSheet("#borderlessMainWindow{border: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;
}
秋叶绚丽 2024-08-27 17:19:34

您的 Qt 目录中有一个示例应用程序: examples/小部件/windowsflags

There is a sample application in your Qt directory: examples/widgets/windowsflags.

尐偏执 2024-08-27 17:19:34

我自己也遇到过这个问题,并在一段时间后弄清楚了。查看 https://github.com/ianbannerman/TrueFramelessWindow 以获取适用于 Windows 和 Windows 的示例代码。 macOS。

Qt::FramelessWindowHint 牺牲了调整大小和最小/最大/关闭,因此可能不是大多数人正在寻找的。

I ran into this myself and figured it out after some time. Check out https://github.com/ianbannerman/TrueFramelessWindow for sample code for both Windows & macOS.

Qt::FramelessWindowHint sacrifices resizing and min/max/close, so is probably not what mot people are looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文