我的任務是為我們的應用程式創建一個自定義的標題欄。它需要有圓角和設定按鈕等。它將專門在 Windows 上運行。
我們的應用程式使用 Qt 和 QML 作為前端。所以我能找到如何做到這一點的唯一方法是使應用程式視窗無框并從頭開始創建標題欄。
這是我的測驗代碼:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
ApplicationWindow {
id: mainWindow
visible: true
visibility: Window.Maximized
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.Window | Qt.WA_TranslucentBackground
//flags: Qt.Window | Qt.WA_TranslucentBackground
color: "#00000000"
TitleBar {
id: mainTitleBar
width: mainWindow.width;
height: mainWindow.height*0.018
color: "#aaaaaa"
onCloseApplication: {
Qt.quit();
}
onMinimizeApplication: {
mainWindow.visibility = Window.Minimized
}
}
Component.onCompleted: {
console.log("Size: " mainWindow.width "x" mainWindow.height)
mainTitleBar.width = mainWindow.width
mainTitleBar.height = mainWindow.height*0.023;
}
Rectangle {
id: content
width: mainWindow.width
height: mainWindow.height - mainTitleBar.height
anchors.top: mainTitleBar.bottom
anchors.left: mainTitleBar.left
color: "#00ff00"
}
}
和
這是標題欄代碼(TitleBar.js 檔案):
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
/*
* Requires setting up of
* -> width
* -> height
* -> title text
* -> icon path.
* -> Background color.
*/
id: vmWindowTitleBar
border.width: 0
x: 0
y: 0
radius: 20
signal closeApplication();
signal minimizeApplication();
// The purpose of this rectangle is to erase the bottom rounded corners
Rectangle {
width: parent.width
height: parent.height/2;
anchors.bottom: parent.bottom
anchors.left: parent.left
border.width: 0
color: parent.color
}
Text {
id: titleBarText
text: "This is The Title Bar"
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: parent.width*0.018
}
Button {
id: minimizeButton
width: height
height: vmWindowTitleBar.height*0.8
anchors.right: closeButton.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: parent.width*0.018
background: Rectangle {
id: btnMinimizeRect
color: vmWindowTitleBar.color
anchors.fill: parent
}
onPressed:{
minimizeApplication()
}
scale: pressed? 0.8:1;
contentItem: Canvas {
id: btnMinimizeCanvas
contextType: "2d"
anchors.fill: parent
onPaint: {
var ctx = btnMinimizeCanvas.getContext("2d");
var h = minimizeButton.height;
var w = minimizeButton.width;
ctx.reset();
ctx.strokeStyle = minimizeButton.pressed? "#58595b": "#757575";
ctx.lineWidth = 6;
ctx.lineCap = "round"
ctx.moveTo(0,h);
ctx.lineTo(w,h);
ctx.closePath();
ctx.stroke();
}
}
}
Button {
id: closeButton
//hoverEnabled: false
width: height
height: vmWindowTitleBar.height*0.8
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: parent.width*0.018
background: Rectangle {
id: btnCloseRect
color: vmWindowTitleBar.color
anchors.fill: parent
}
onPressed:{
closeApplication()
}
scale: pressed? 0.8:1;
Behavior on scale{
NumberAnimation {
duration: 10
}
}
contentItem: Canvas {
id: btnCloseCanvas
contextType: "2d"
anchors.fill: parent
onPaint: {
var ctx = btnCloseCanvas.getContext("2d");
var h = closeButton.height;
var w = closeButton.width;
ctx.reset();
ctx.strokeStyle = closeButton.pressed? "#58595b": "#757575";
ctx.lineWidth = 2;
ctx.lineCap = "round"
ctx.moveTo(0,0);
ctx.lineTo(w,h);
ctx.moveTo(w,0);
ctx.lineTo(0,h);
ctx.closePath();
ctx.stroke();
}
}
}
}
現在問題是最小化應用程式。我意識到的第一件事是,當使用 Qt.FramelessWindowHint 標志時,圖示不會出現在 Windows 任務欄中。此外,如果我將其最小化,則會發生這種情況:

如果我點擊它,它不會恢復。
所以我的問題是,有沒有辦法在按下最小化按鈕時重現常規的最小化行為?
或者,有沒有一種方法可以完全自定義應用程式的標題欄,以便實作我們的 UI 設計師設定的外觀?
注意:當前的外觀只是一個快速測驗。我還沒有設定漸變、字體或上述設定按鈕。
uj5u.com熱心網友回復:
至于我,玩無框視窗和透明背景是一種解決方法。據我所知,將自定義形狀應用于視窗的唯一方法是QWindow::setMask。罪孽Window源于QWindow你可以這樣做。
例如,在 main.cpp 中:
QWindow *wnd = qobject_cast<QWindow *>(engine.rootObjects().at(0));
auto f = [wnd]() {
QPainterPath path;
path.addRoundedRect(QRectF(0, 0, wnd->geometry().width(), wnd->geometry().height()), 30, 30);
QRegion region(path.toFillPolygon().toPolygon());
wnd->setMask(region);
};
QObject::connect(wnd, &QWindow::widthChanged, f);
QObject::connect(wnd, &QWindow::heightChanged, f);
f();
由于您從視窗本身“剪切”了形狀,不包括標題欄和框架,您可以保持視窗標志不變。
uj5u.com熱心網友回復:
以這種方式看,我嘗試創建一些你所做的事情,但完全改變你的代碼。
最小化視窗后更改視窗大小的問題是您沒有為視窗設定初始值width,height因此當您最小化應用程式時,它以最小寬度和高度顯示。
所以你只需要添加這個main.qml并將初始寬度和高度設定為最大值。
width: maximumWidth
height:maximumHeight
但在下面的代碼中,我也更改了其他內容。
例如,你不需要發射信號,然后趕上他們在main.qml你要訪問mainWindow的TitleBar.qml。
在 TitleBar.qml 中:
import QtQuick 2.0
import QtQuick.Controls 2.0
Rectangle {
anchors.fill: parent
height: 30
Row {
id: row
anchors.fill: parent
Label {
id: label
text: qsTr("Title ")
}
Button {
id: button
x: parent.width -80
text: qsTr("close")
onClicked:
{
mainWindow.close()
}
}
Button {
id: button1
x: parent.width -160
width: 90
text: qsTr("Minimized")
onClicked:
{
mainWindow.showMinimized()
}
}
}
}
在 main.qml 中:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
import "."
Window {
id: mainWindow
visible: true
visibility: Window.FullScreen
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.Window | Qt.WA_TranslucentBackground
width: maximumWidth
height:maximumHeight
Rectangle {
id: content
anchors.fill: parent
x: 0
y: 20
width: mainWindow.width
height: mainWindow.height - mainTitleBar.height
anchors.top: mainTitleBar.bottom
anchors.left: mainTitleBar.left
color: "#00ff00"
}
TitleBar {
id: mainTitleBar
color: "#aaaaaa"
anchors.bottomMargin: parent.height -40
anchors.fill: parent
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/359390.html
下一篇:C 獲取樹的最低級別
