【问题标题】:How to create frameless window style like VS2013 using QT5如何使用QT5创建类似VS2013的无框窗口样式
【发布时间】:2014-07-11 14:15:51
【问题描述】:

我的应用程序窗口没有框架,但它有标题栏、最小化、最大化和关闭按钮,就像普通窗口一样,当我用鼠标拖动标题栏时,它可以像其他窗口一样移动。

我在 QStyle、Q StyleSheet 模块甚至 WindowExtras 中都找不到这种风格...

有人告诉我,QML 可以轻松实现。这是否意味着我应该使用一些资源图像文件(最小化、最大化和关闭按钮)创建窗口,使用 QML 制作标题栏,然后使用 C++ 代码禁用原始窗口框架?

或者有什么更好的方法吗?

我是 qt 新手,任何建议都会有所帮助。

这里是快捷链接,我的操作系统是 Windows 7:

还有:

【问题讨论】:

  • 请使用stackoverflow的图片托管。这些外部照片链接往往会随着时间的推移而消失。

标签: qt styles window


【解决方案1】:

我创建了一个小例子,说明如何在 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);

  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;
}

【讨论】:

  • 知道为什么无框窗口比普通窗口慢这么多吗?
【解决方案2】:

偶然发现了这个寻求解决方案。现在在Qt 5.7分享解决方案

Qt::FramelessWindowHint

生成无边框窗口。用户不能移动或调整大小 通过窗口系统实现无边框窗口。在 X11 上,结果 标志取决于窗口管理器及其理解能力 主题和/或 NETWM 提示。大多数现有的现代窗口管理器都可以 处理这个。

#include "mainwindow.h"
#include <QApplication>

int main( int argc, char *argv[] )
{
    QApplication app( argc, argv );

    MainWindow window;
    window.setWindowFlags( Qt::FramelessWindowHint );
    window.setParent( 0 );
    window.show( );

    return app.exec();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 2011-04-23
    相关资源
    最近更新 更多