qml窗口无边框带阴影

总结了两个方式,推荐使用第一种

  1. 使用RectangularGlow来达到阴影的目的

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.0
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0

Window {
    width: 840
    height: 680
    visible: true
    color: "transparent"
	
	x:Screen.width/2 - width/2
	y:Screen.height/2 - height/2
	
	property int titlebar_wrapper_size:40	
	id:registerWindow
	
    flags: Qt.FramelessWindowHint |
       Qt.WindowMinimizeButtonHint |
       Qt.Window
	   
	function startLogin()
	{
		var userName = registername.text

		if( userName != ""  ){
			id_mesDialog.icon = StandardIcon.Information
			id_mesDialog.text = "登陆成功"			
			id_mesDialog.open()
		}else{
			id_mesDialog.icon = StandardIcon.Critical
			id_mesDialog.text = "请输入用户名"
			id_mesDialog.open()
		}
	}
	
	MessageDialog {
		id:id_mesDialog
		title: "提示框"
		icon: StandardIcon.Question
		text: ""
		standardButtons: StandardButton.Ok
		Component.onCompleted: visible = false
	}
	   
    Item {
        anchors.fill: parent
        RectangularGlow {
            id: effect
            anchors.fill: rect
            glowRadius: 10
            spread: 0.2
            color: "#406A6F76"
            cornerRadius: rect.radius + glowRadius
        }
        Rectangle {
            id: rect
            color: "white"
            anchors.centerIn: parent
            width: registerWindow.width - 40
            height: registerWindow.height - 40
            radius: 4
			
			MouseArea {
				id:dragparentwindow
				width: parent.width
				height: 57
				property real lastMouseX: 0
				property real lastMouseY: 0
				onPressed: {
					lastMouseX = mouseX
					lastMouseY = mouseY
				}
				onMouseXChanged: registerWindow.x += (mouseX - lastMouseX)
				onMouseYChanged: registerWindow.y += (mouseY - lastMouseY)
			}
			
			Rectangle{
				id:titlebar
				width: parent.width
				Rectangle{
					id:appclose
					height: titlebar_wrapper_size
					y:0
					width: titlebar_wrapper_size
					anchors.right: parent.right
					Text{
						text: "×"
						anchors.horizontalCenter: parent.horizontalCenter
						font.pointSize: 20
					}
					MouseArea{
						width: parent.width
						height: parent.height
						hoverEnabled: true
						onEntered: appclose.color="#ddd"
						onExited: appclose.color="#fff"
						onClicked: Qt.quit()
					}
				}
				Rectangle{
					id:appminimize
					height: titlebar_wrapper_size
					y:0
					width: titlebar_wrapper_size
					anchors.right: appclose.left
					Text{
						text: '-'
						font.family: "Microsoft Yahei"
						anchors.horizontalCenter: parent.horizontalCenter
						font.pointSize: 15
					}
					MouseArea{
						width: parent.width
						height: parent.height
						hoverEnabled: true
						onEntered: appminimize.color="#ddd"
						onExited: appminimize.color="#fff"
						onClicked: registerWindow.visibility = Window.Minimized
					}
				}
				
				Text{
					text:"XTE"
					font.family: "Microsoft Yahei"
					font.pointSize: 85
					anchors.horizontalCenter: parent.horizontalCenter
					y:70
				}

				TextField{
					id:registername
					background: Rectangle {
						border.color: "#0000CD"
						border.width: 1
						radius: 5
						antialiasing:true
					 }
					width:400
					height:50
					y:420
					font.pointSize: 17
					font.family: "Microsoft Yahei"
					placeholderText: " Enter a nickname ..."
					anchors.horizontalCenter: parent.horizontalCenter
				}

				Button{
					id:login
					text:"Login"
					background: Rectangle {
						anchors.fill: parent
						radius: 3
						color: login.down ? "#0084ff" :
								 login.hovered ? "#1AAD19" : "#0084ff"

					}
					anchors.horizontalCenter: parent.horizontalCenter
					anchors.top: registername.bottom
					anchors.topMargin: 17
					font.family: "Microsoft Yahei"
					font.pointSize: 22
					onClicked: startLogin()
				}
			}
        }				
    }
}
  1. qml中的主界面是Rectangle,可以新建一个普通的widget,然后在widget类中新建QQuickView m_pQmlContainer = new QQuickView();然后根据这个QQuickView产生一个widget,作为当前窗口的子窗口,然后将当前窗口的标题栏隐藏。通过自绘来实现阴影。有个问题,MessageDialog弹出的时候,会有警告,并且不是模态的框。QQuickView(0x2de9437b5b0) must be a top level window
    main.cpp
#include <QApplication>
#include <QQuickView>
#include "mainWidget.h"
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);
	MainWidget mainWidget;
	mainWidget.SetQmlFile(QStringLiteral("qrc:/main.qml"));
	mainWidget.show();  
	
    return app.exec();
}

mainWidget.h

#ifndef __MAIN_WIDGET_H_
#define __MAIN_WIDGET_H_
#include <QQuickView>
#include <QWidget>
#include <QPixmap>
#include <QPaintEvent>

class MainWidget : public QWidget
{
	Q_OBJECT
public:
	explicit MainWidget(QWidget *parent = nullptr);
	~MainWidget();
	void SetQmlFile(QString strQmlFile);
	
private:
	QQuickView *m_pQmlContainer;
	QPixmap m_shadow;
	
protected:
	void paintEvent(QPaintEvent *e);
};

#endif

mainWidget.cpp

#include "mainWidget.h"
#include <QHBoxLayout>
#include <QQmlContext>
#include <QDebug>
#include <QPainter>

MainWidget::MainWidget(QWidget *parent): QWidget(parent),m_shadow(":/window_shadow.png")
{
	m_pQmlContainer = new QQuickView();
    QHBoxLayout* layout = new QHBoxLayout(this);
	QWidget* pWidget = QWidget::createWindowContainer(m_pQmlContainer,this);
	
	layout->addWidget(pWidget);
	layout->setContentsMargins(5,3,5,7);
	setLayout(layout);
	
	setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint);	
	m_pQmlContainer->rootContext()->setContextProperty("window",this);
	setFixedSize(910,610);
}

MainWidget::~MainWidget()
{
	
}

void MainWidget::SetQmlFile(QString strQmlFile)
{
	m_pQmlContainer->setSource(strQmlFile);
}

void MainWidget::paintEvent(QPaintEvent* e)
{
	QPainter painter(this);

    QRect bottom(5, 136, 200, 7);
    QRect top(5, 0, 200, 3);
    QRect left(0, 3, 5, 133);
    QRect right(205, 3, 5, 133);
    QRect topRight(205, 0, 5, 3);
    QRect topLeft(0, 0, 5, 3);
    QRect bottomLeft(0, 136, 5, 7);
    QRect bottomRight(205, 136, 5, 7);

    QRect tBottom(5, this->height() - 7, this->width() - 10, 7);
    QRect tTop(5, 0, this->width() - 10, 3);
    QRect tLeft(0, 3, 5, this->height() - 10);
    QRect tRight(this->width() - 5, 3, 5, this->height() - 10);
    QRect tTopLeft(0, 0, 5, 3);
    QRect tTopRight(this->width() - 5, 0, 5, 3);
    QRect tBottomLeft(0, this->height() - 7, 5, 7);
    QRect tBottomRight(this->width() - 5, this->height() - 7, 5, 7);

    painter.drawPixmap(tBottom, m_shadow, bottom);
    painter.drawPixmap(tTop, m_shadow, top);
    painter.drawPixmap(tLeft, m_shadow, left);
    painter.drawPixmap(tRight, m_shadow, right);
    painter.drawPixmap(tTopRight, m_shadow, topRight);
    painter.drawPixmap(tTopLeft, m_shadow, topLeft);
    painter.drawPixmap(tBottomLeft, m_shadow, bottomLeft);
    painter.drawPixmap(tBottomRight, m_shadow, bottomRight);
	

}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.0
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2

Rectangle {
    id: loginWin
	anchors.fill: parent
    SystemPalette { id: activePalette }

    //背景图片
    Image
    {
        id: background
        anchors { top: parent.top; bottom: parent.bottom }
        anchors.fill: parent
        source: "./background.jpeg"
        fillMode: Image.PreserveAspectCrop
    }
	
	MouseArea {
		anchors.fill: parent
		property variant previousPosition
		onPressed: {
			previousPosition = Qt.point(mouseX,mouseY)
		}
		onPositionChanged: {
			if(pressedButtons == Qt.LeftButton){
				var dx = mouseX - previousPosition.x
				var dy = mouseY - previousPosition.y
				window.pos = Qt.point(window.pos.x + dx,window.pos.y + dy)
			}
		}
	}
	
	MessageDialog {
		id:id_mesDialog
		title: "提示框"
		icon: StandardIcon.Question
		text: ""
		standardButtons: StandardButton.Ok
		Component.onCompleted: visible = false
	}
	
	function login()
	{
		var userName = line.text
		var password = linePassword.text
		if( userName == "admin" && password == "123456" ){
			id_mesDialog.icon = StandardIcon.Information
			id_mesDialog.text = "登陆成功"
			
			id_mesDialog.open()
		}else{
			id_mesDialog.icon = StandardIcon.Critical
			id_mesDialog.text = "用户名或密码错误"
			id_mesDialog.open()
		}
	}

    //顶栏
    Item
    {
        id: topBar
        width: loginWin.width; height: loginWin.height*0.05
        anchors.top: loginWin.top
        anchors.topMargin: 20

        Text
        {
            id: title
            anchors { top: parent.top; horizontalCenter: parent.horizontalCenter }
            text: "登陆"
            font.bold: true
            font.pointSize: loginWin.height * 0.05 * 0.7
            color: "dark red"
        }
    }

    //空白栏
    Item
    {
        id: space
        width: loginWin.width; height: loginWin.height * 0.1
        anchors.top: topBar.bottom
    }	

    // 登录框
    Rectangle {
        id: loginRect
        width: loginWin.width * 0.8
        height: loginWin.height * 0.3
        anchors { top: space.bottom; horizontalCenter: parent.horizontalCenter }
        border.color: "#707070"
        color: "transparent"

        LineInput
        {
            id: line
            width: loginRect.width * 0.8; height: loginRect.height * 0.2
            fontSize:height * 0.7
            anchors { horizontalCenter: loginRect.horizontalCenter; top: loginRect.top; topMargin: 8 }
            hint: "请输入用户号"
        }

        LineInput
        {
			id: linePassword
            width: loginRect.width * 0.8; height: loginRect.height * 0.2
            fontSize:height * 0.7
            anchors { horizontalCenter: loginRect.horizontalCenter; bottom: loginButton.top;  bottomMargin: loginRect.height * 0.1 }
            hint: "请输入密码"
        }

        Button
        {
            id: loginButton
            width: loginRect.width * 0.35; height: loginRect.height * 0.2
            anchors { left: loginRect.left; leftMargin: 28; bottom: loginRect.bottom; bottomMargin: 8 }
            text: "登陆"
            onClicked: login()
        }

        Button
        {
            id: quitButton
            width: loginRect.width * 0.35; height: loginRect.height * 0.2
            anchors { right: loginRect.right; rightMargin: 28; bottom: loginRect.bottom; bottomMargin: 8 }
            text: "退出"
            onClicked: window.close()
        }
    }
}

Button.qml

import QtQuick 2.0

Rectangle {
    id: container

    property string text: "Button"

    signal clicked

    width: buttonLabel.width + 20; height: buttonLabel.height + 5
    border { width: 1; color: Qt.darker(activePalette.button) }
    antialiasing: true
    radius: 8

    // color the button with a gradient
    gradient: Gradient {
        GradientStop {
            position: 0.0
            color: {
                if (mouseArea.pressed)
                    return activePalette.dark
                else
                    return activePalette.light
            }
        }
        GradientStop { position: 1.0; color: activePalette.button }
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: container.clicked();
    }

    Text {
        id: buttonLabel
        anchors.centerIn: container
        color: activePalette.buttonText
        text: container.text
    }
}

LineInput.qml

import QtQuick 2.0

FocusScope {
    id: wrapper

    // 定义可通过元对象系统访问的属性
    property alias text: input.text
    property alias hint: hint.text
    property int fontSize: 18

    // 自定义信号
    signal accepted

    Rectangle {
        anchors.fill: parent
        border.color: "#707070"
        color: "#c1c1c1"
        radius: 4

        // 输入栏隐藏文本
        Text {
            id: hint
            anchors { fill: parent; leftMargin: 14 }
            verticalAlignment: Text.AlignVCenter
			horizontalAlignment: input.activeFocus ? Text.AlignLeft : Text.AlignHCenter
            text: "Enter word"
            font.pixelSize: fontSize
            color: "#707070"
            opacity: input.length ? 0 : 1
        }

        TextInput {
            id: input
            focus: true
            anchors { left: parent.left; leftMargin: 14; right: parent.right; top: parent.top; bottom: parent.bottom }
            verticalAlignment: Text.AlignVCenter
			horizontalAlignment: Text.AlignHCenter
            font.pixelSize: fontSize
            color: "black"
            maximumLength: 8

            onAccepted: wrapper.accepted()
        }
    }
}

window_shadow.png是这样的,大小为210*143,并且主窗口设置了margin,layout->setContentsMargins(5,3,5,7),留出来的边框用于自绘阴影。
window_shadow.png的效果

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值