Code Monkey home page Code Monkey logo

Comments (21)

BillHoo avatar BillHoo commented on May 26, 2024 3

@tishion 这几个月忙起来忘了回复你了,感谢你之前给我的思路指点。我这边也实现了阴影的效果和其他正常操作。具体方案感觉和你的不一样,不过核心思路是一样的,阴影是一个 Qt::Tool,再次感谢。

@zouyikang 我是借鉴了tishion的思路,但是我实现得更加繁琐和另类了,仅供参考:

阴影是一个独立的通用类,属性就是 tishion 之前提供的。之所以要具备 Qt::Tool 类型我觉得大致是因为这个类型的窗体或者Widget不会在任务栏上出现一个小方框,不然的话阴影也会被当作一个独立的窗口显示在任务栏上。

我的阴影 S 是一个完全独立的Widget,属性设置了:

    this->setAttribute(Qt::WA_DeleteOnClose); // from tishion
    this->setAttribute(Qt::WA_TranslucentBackground); // from tishion
    this->setAttribute(Qt::WA_TransparentForMouseEvents);
    this->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); // from tishion
    this->setStyleSheet("background-color: grey; border: none;");

C 是我需要添加阴影效果的内容窗体或Widget。Widget C 是 S 的 parent(我现在记不得为什么要有这个parent了,估计是 Qt::Tool 属性的原因),但是仅仅只是 QObject 层面的 parent,S 可以独立于 C 进行任何显示、隐藏、改变大小等操作,S 不能放进 C 的任何一个布局继承体系中(从而避免了我这个问题之初遇到的情况,就是布局继承体系中使用了 Qt::WA_TranslucentBackground 这个属性的话,QCEF 渲染时就不显示了)。

C 类包含 S 类的成员变量,针对 C 的每一个窗体操作(移动、大小变更等)都对 S 人为地做同样的设置和处理。假设我要阴影宽度为20px,C 的大小现在变更为 40px * 40px,则 S 的大小我们要设置成 60px * 60px,且移动 S 使之中心点与 C 的中心点对其。这样才能从视觉上看出 C 的阴影是 S。

tishion 的方案是 C 是浮动于 S 之上的,也就是说阴影 S 始终位于底部。但是我的却完全相反,由于 Qt::Tool 或是别的什么原因(我不记得了 Orz...),S 只要一显示出来就始终覆盖于 C 之上,位于 Z 轴的 top 层,相当于 C 始终位于底部了,导致比 C 还大的 S 整个把 C 挡住了。像这样:

1

因此想办法在 S 中间挖了个洞,使用了 QT 的 setMask API,在 S 正中间挖了一个大小为 C 的(包括 C 的圆角形状)的洞,使得 C 可以透过这个洞显示出来。然后添加了 Qt::WA_TransparentForMouseEvents 属性给 S,使得在最上层的 S 始终不挡住任何鼠标操作,直接把鼠标操作传递给位于底层的 C。

我这里的整个逻辑就是这样。但是总感觉处理的过于复杂,tishion之前说的步骤要少很多。还有很多细节处理的具体问题会遇到。你说的 active 相关问题我没有遇到过,所有窗体 activate、modal 等都正常,大致说一下我对大小和窗体状态变更的一些处理供你参考:

C 窗体移动:

void BasicDialog::moveEvent(QMoveEvent *ev) {
    _basic_shadow->SetShadowPos(ev->pos()); // 同时移动阴影 S,使之中心与 C 对齐
}

C 窗体 Resize

void BasicDialog::resizeEvent(QResizeEvent *e) {
    setRoundedCornerMask(); // 这是我绘制圆角的逻辑

    _basic_shadow->SetShadowBodyFixedSize(e->size()); // 同时设置阴影大小,函数实现中设置的阴影大小始终比这个 size() 大一圈儿,从而实现 C 周围的阴影效果。

    // ...
}

C 窗体 Show

void BasicDialog::showEvent(QShowEvent *e) {
    setRoundedCornerMask();

    _basic_shadow->show(); // 由于 S 与 C 不具备任何布局继承关系,因此 S show 出来后,默认位于屏幕左上角,与 C 无关。
    _basic_shadow->SetShadowPos(this->pos()); // 移动 S 使之与 C 中心重合
}

C 窗体 Hide

void BasicDialog::hideEvent(QHideEvent *e) {
    _basic_shadow->hide();
}

from qcefview.

zhulingbiezhi avatar zhulingbiezhi commented on May 26, 2024

我也遇到了,没解决,哈哈,你尝试设置qcefview的父窗体为window,并且父窗体的父亲为null

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

这样不行,我这边是基于 QWidget的APP,所有窗体都是继承自一个顶级 QWidget,该 Widget 用来显示阴影和自定义 Titlebar,顶级 Widget 设置了背景透明选项。

具体的技术原因QT官方没有明确的解释,但是好多论坛都说了,反正就是“不能”将一个QWindow或者QQuick2的窗体嵌入进背景透明的 QWidget 中。

如果这两者就是不能兼容,我实在是找不到解决方案了。

from qcefview.

zhulingbiezhi avatar zhulingbiezhi commented on May 26, 2024

这是qt的bug吧,我只做了cef的api,嵌入到客户端程序中也发现这个问题,我直接注释了

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

估计是,我在QT Jira 中搜Bug,倒是有很多相关问题,但是没有一个给出了官方解答,基本都被直接关闭了。

你说的“直接注释了”是什么意思呢?注释掉QCEF中的哪句话能解决这个问题?

from qcefview.

zhulingbiezhi avatar zhulingbiezhi commented on May 26, 2024

我之前做项目也是用你这样的方案去实现边缘透明效果,后来发现在xp不兼容出现黑边,所以后面改为采用windows API实现边缘毛玻璃效果

from qcefview.

zhulingbiezhi avatar zhulingbiezhi commented on May 26, 2024

我把透明函数注释了

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

哦。。。。。透明函数注释了那我这边整个方案就洗白了。我这里不需要支持XP系统了。我赶项目进度,这种透明 Widget 方案是最快的。不知道你说的 windows api 是哪一个,能给我个MSDN链接么 我去参考下。

from qcefview.

zhulingbiezhi avatar zhulingbiezhi commented on May 26, 2024

我代码都找不到,刚辞职了,你可以百度下windows毛玻璃

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

好的 我去搜一下,多谢你提供的信息。

from qcefview.

tishion avatar tishion commented on May 26, 2024

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

链接Qt的Bug以便跟踪这个问题:
https://bugreports.qt.io/browse/QTBUG-63199

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

@tishion 你好,我主要需求是窗口的自定义阴影效果。Qt里面顶级窗口没办法在窗体之外绘制内容,因此我把所有contents绘制到了一个widget中,并把阴影绘制到这个widget的边上,调整widget到主窗体的边距用来显示这个阴影。主窗体的作用只是显示阴影和这个widget。所以主窗体需要背景透明。

from qcefview.

tishion avatar tishion commented on May 26, 2024

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

好的,我去看看

from qcefview.

tishion avatar tishion commented on May 26, 2024

给你一点提示吧,Shadow做一个单独的窗口,属性设置为:

	setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
	setAttribute(Qt::WA_DeleteOnClose, TRUE);
	setAttribute(Qt::WA_TranslucentBackground);

真正的窗口我这里叫ContentWindow,是浮在这个ShadowWindow之上的一个Qwidget,ContentWindow和ShadowWindow并不具有父子关系,ShadowWindow接收到所有的size和pos相关的event的时候都要对ContentWindow处理适应新的size和pos。

from qcefview.

tishion avatar tishion commented on May 26, 2024

当然生命周期也要控制好。其实我的代码都写的很通用,一个类文件给你就可以直接用了,但是你还是自己搞搞吧。

from qcefview.

BillHoo avatar BillHoo commented on May 26, 2024

好的多谢,代码是你的知识结晶我也无意索取,感谢你提供的思路,我去尝试一下也是对我自己的提高。多谢。

from qcefview.

zouyikang avatar zouyikang commented on May 26, 2024

@BillHoo 请问你的这个问题完全解决没 我现在遇到当ContentWindow active的时候 ShadowWindow 无法raisze起来,有些操作能使ShadowWindow窗口的Z序发送变化。

from qcefview.

zouyikang avatar zouyikang commented on May 26, 2024

@BillHoo 谢谢你的回复,很详细,解决了我的问题。

from qcefview.

bairutai avatar bairutai commented on May 26, 2024

给你一点提示吧,Shadow做一个单独的窗口,属性设置为:

	setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
	setAttribute(Qt::WA_DeleteOnClose, TRUE);
	setAttribute(Qt::WA_TranslucentBackground);

真正的窗口我这里叫ContentWindow,是浮在这个ShadowWindow之上的一个Qwidget,ContentWindow和ShadowWindow并不具有父子关系,ShadowWindow接收到所有的size和pos相关的event的时候都要对ContentWindow处理适应新的size和pos。

可以开源么,抱歉做伸手党,按照@BillHoo 的思路做了一遍,遇到白屏的问题,层级关系处理不好

from qcefview.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.