QT自定义标题栏(最大化、最小化和无边框拉伸等--可直接使用)和样式设计(美化)

1、自定义标题栏

1.1一个很好的边框window设计框架
项目地址 

https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window

下载上面两个文件(.h和.cpp)之后,定义一个myWindow.h文件

class myWindow : public CFramelessWindow
{
	Q_OBJECT

public:
	explicit myWindow (QWidget* parent = nullptr)
		: CFramelessWindow(parent)
	{ }

	virtual void onShowMinimized() { showMinimized(); }

	virtual void onToggleMaxNormal()
	{
		if (isMaximized()) {
			showNormal();
		}
		else {
			showMaximized();
		}
	}

	virtual void onClose() { close(); }

	void showCenter(int offsetX = 0, int offsetY = 0)
	{
		const auto screenRect = getScreenRect(true);
		// 获取对话框的大小
		QSize dialogSize = sizeHint();
		// 计算对话框的位置,使其位于屏幕中央
		int x = (screenRect.width() - dialogSize.width()) / 2;
		int y = (screenRect.height() - dialogSize.height()) / 2;
		move(x, y);
		show();
	}

	// 获取当前屏幕尺寸区域
	static QRect getScreenRect(bool available = true)
	{
		const int screenIndex = getScreenIndex();
		return available ? qApp->screens().at(screenIndex)->availableGeometry() : qApp->screens().at(screenIndex)->geometry();
	}

	// 获取当前屏幕索引
	static int getScreenIndex()
	{
		if (const int screenCount = qApp->screens().count(); screenCount > 1) {
			// 找到当前鼠标所在屏幕
			const QPoint pos = QCursor::pos();
			for (int i = 0; i < screenCount; ++i) {
				if (qApp->screens().at(i)->geometry().contains(pos)) {
					return i;
				}
			}
		}
		return 0;
	}
};

1.2 标题栏UI

注意:弹簧扩展选择MinimunExpanding,否则最大化间距会变大!

若需要menubar,则widget里面的menubar直接在ui文件里面加入

<item>
       <widget class="QMenuBar" name="menuBar">
        <property name="minimumSize">
         <size>
          <width>400</width>
          <height>0</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
          <width>440</width>
          <height>16777215</height>
         </size>
        </property>
        <property name="styleSheet">
         <string notr="true"/>
        </property>
       </widget>
      </item>

构建自己的标题栏即可

class titleBarTest : public myWindow
{
	Q_OBJECT

public:
	titleBarTest(QWidget* parent = nullptr);
	~titleBarTest();
	void buildTitleBar();
private:
	Ui::titleBarTestClass ui;
};
void titleBarTest::buildTitleBar()
{
	const auto titleBar = ui.titleBar;
	titleBar->setObjectName("titleBar");
	this->setBtnMin(ui.minBtn);
	this->setBtnMax(ui.maxBtn);
	this->setBtnClose(ui.closeBtn);

	connect(ui.minBtn, &QToolButton::clicked, this, &Window::onShowMinimized);
	connect(ui.maxBtn, &QToolButton::clicked, this, [this] {
		// change icon
		ui.maxBtn->setProperty("class", this->isMaximized() ? "max" : "normal");
		this->onToggleMaxNormal();
		});

	showCenter();
	connect(ui.closeBtn, &QToolButton::clicked, this, &titleBarTest::onClose);
	setTitleBar(titleBar);
}
在实际的项目开发中,只需要将你主窗口的widget继承于myWindow即可,并在你的widget添加一个如上的标题栏UI,即可实现所需要的功能。

2、样式设计

提供一种自己使用的设计方案


QWidget#titleBar {
background-color: #2354a4;
}


/*  关闭按钮 */
QToolButton#closeBtn {
    background-color: transparent; 
    border: none; 
    color: #000000;
	
}

QToolButton#closeBtn:hover {
    background-color: #ff0000;
}

/*  最大化按钮 */
QToolButton#maxBtn {
    background-color: transparent; 
    border: none; 
    color: #000000;
	
}

QToolButton#maxBtn:hover {
    background-color:  #808080;
}

/*  最小化按钮 */
QToolButton#minBtn {
    background-color: transparent; 
    border: none; 
    color: #000000;
}

QToolButton#minBtn:hover {
    background-color:  #808080;
}

/* logo按钮 */
QPushButton#logo {
    background-color:  transparent; /* 按钮背景颜色 */
	border: none;
}

QToolButton#closeBtn_2:hover {
   background-color: #ff0000;
    border: 1px solid #ff0000;
}

QToolButton#closeBtn_3:hover {
   background-color: #ff0000;
    border: 1px solid #ff0000;
}

QToolButton#closeBtn_3:hover { 
	background-color: #ff0000 !important; 
	border: 2px solid #ff0000 !important; 
}

/*  菜单栏 */


QMenuBar {
    background-color: @primaryColor;
    padding: 2px;
    border: none;
    font-size: 13px;
    color: white;
    selection-background-color: #73C7FF;
}

QMenuBar:focus {
    border: 1px solid #9FCBFF;
}

QMenuBar::item {
    background: transparent;
    padding: 9px 16px 9px 16px;
    font-size: 16px;
    font-weight: bold;
}

QMenuBar::item:selected {
    background: transparent;
    background-color: #3265B9;
    /*background-color: desaturate(@primaryColor, 15%); *//* 主题色的饱和度降低一些,就是悬浮颜色 */
}

QMenuBar::item:pressed {
    border: 0px solid #C9CDD0;
    background-color: #3265B9;
    /* background-color: desaturate(@primaryColor, 15%); */
}

/* 菜单   菜单边框 (上、下边框 菜单项是其内容)   菜单项(上右下左边框,文字内容)*/
QMenu {
    background-color: transparent;
    border-radius: 0px;
    
    padding-top: 0px;              /* 菜单项内容到上边框的距离 */
    padding-bottom: 0px;
    margin: 0px;                 /* 菜单内容 边框到边界的距离 */
    padding-right: 0px;
    min-width: 150px;
}

QMenu::item {
    min-width: 150px;
    background-color: #ececec;
    border-radius: 0px;
    padding: 9px 15px 9px 17px;
    color: #333333;
    border: none;
    font-size: 12px;
}

 QMenu::item:selected { 
    background-color: #2354a4; 
    color:white;
 }

QMenu::icon {
    padding-left: 10px;
    width: 14px;
    height: 14px;
}

QMenu::item:pressed {
    border: 0px solid #C9CDD0;
    background-color: #ff0000;
    /* background-color: desaturate(@primaryColor, 15%); */
}

QMenu::item:!enabled {
    border: 0px;
    border-bottom: 0px solid #444444;
    background-color: #C4C4C4;
}



QMenu::indicator {
    padding-left: 8px;
    width: 12px;
    height: 12px;
    /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */
    /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */
}


实际开发中,导入css文件即可

QString path = "color.qss";
QFile file(path);

if (file.open(QFile::ReadOnly | QIODevice::Text)) {
	QString qss = QLatin1String(file.readAll());
	this->setStyleSheet(qss);
	file.close();
}

3、 结果

样式表待完善,先用着~~~~~

如果对你有用,那就点个赞呗!感谢~~~~

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Qt的QMainWindow类来自定义标题栏。 首先,需要将窗口的标题栏隐藏起来,可以使用setWindowFlags函数来实现: ```cpp setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); ``` 这里使用了`Qt::FramelessWindowHint`参数来隐藏窗口的标题栏,`Qt::WindowSystemMenuHint`参数来显示窗口的系统菜单,`Qt::WindowMinMaxButtonsHint`参数来显示窗口的最大化最小化按钮。 接下来,需要在窗口中添加自定义标题栏。可以使用QWidget来实现,将其作为QMainWindow的子控件添加到窗口中: ```cpp QWidget *titleBar = new QWidget(this); titleBar->setObjectName("TitleBar"); titleBar->setStyleSheet("QWidget#TitleBar{background-color: #F0F0F0;}"); titleBar->setFixedHeight(30); QHBoxLayout *layout = new QHBoxLayout(titleBar); layout->setMargin(0); layout->setSpacing(0); QLabel *titleLabel = new QLabel(titleBar); titleLabel->setText("My Title"); titleLabel->setStyleSheet("QLabel{font-size: 14px;color: #333333;}"); layout->addWidget(titleLabel); layout->addStretch(); QToolButton *minButton = new QToolButton(titleBar); minButton->setObjectName("MinButton"); minButton->setStyleSheet("QToolButton{border:none;background-color:transparent;}" "QToolButton:hover{background-color:#E0E0E0;}" "QToolButton:pressed{background-color:#D0D0D0;}"); minButton->setIcon(QIcon(":/titlebar/minimize.png")); minButton->setFixedSize(30, 30); layout->addWidget(minButton); QToolButton *maxButton = new QToolButton(titleBar); maxButton->setObjectName("MaxButton"); maxButton->setStyleSheet("QToolButton{border:none;background-color:transparent;}" "QToolButton:hover{background-color:#E0E0E0;}" "QToolButton:pressed{background-color:#D0D0D0;}"); maxButton->setIcon(QIcon(":/titlebar/maximize.png")); maxButton->setFixedSize(30, 30); layout->addWidget(maxButton); QToolButton *closeButton = new QToolButton(titleBar); closeButton->setObjectName("CloseButton"); closeButton->setStyleSheet("QToolButton{border:none;background-color:transparent;}" "QToolButton:hover{background-color:#E0E0E0;}" "QToolButton:pressed{background-color:#D0D0D0;}"); closeButton->setIcon(QIcon(":/titlebar/close.png")); closeButton->setFixedSize(30, 30); layout->addWidget(closeButton); setMenuWidget(titleBar); ``` 这里创建了一个名为"titleBar"的QWidget作为窗口的标题栏,设置了其背景颜色和固定高度。然后创建了一个水平布局并添加了一个QLabel、一个最小化按钮、一个最大化按钮和一个关闭按钮。最后将标题栏设置为窗口的菜单控件,用于显示系统菜单。 需要注意的是,上面的代码中使用了三个图标文件,需要将它们添加到Qt项目中,并在代码中使用正确的路径。 ```qrc <RCC> <qresource prefix="/titlebar"> <file>minimize.png</file> <file>maximize.png</file> <file>close.png</file> </qresource> </RCC> ``` 最后,需要在窗口中实现标题栏按钮的功能。可以在按钮的clicked信号中实现最小化最大化和关闭窗口的功能: ```cpp connect(minButton, &QToolButton::clicked, this, &QMainWindow::showMinimized); connect(maxButton, &QToolButton::clicked, this, &QMainWindow::showMaximized); connect(closeButton, &QToolButton::clicked, this, &QMainWindow::close); ``` 这里使用Qt的槽函数机制来实现按钮的功能。 完整的示例代码可以参考下面的链接: https://github.com/qt/qtbase/blob/dev/examples/widgets/widgets/framelesswindow/main.cpp

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值