求助,关于Qt的窗口半透明,窗口上的空间不透明

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求助,关于Qt的窗口半透明,窗口上的空间不透明相关的知识,希望对你有一定的参考价值。

参考技术A 1.窗口整体透明,但是窗体上的控件不透明。 通过设置窗体的背景色来实现,将背景色设置为全透。 QPalette pal = palette();
pal.setColor(QPalette::Background, QColor(0x00,0xff,0x00,0x00));
setPalette(pal); 试验效果: 窗体标题栏不透明; 窗体客户区上的控件不透明,QLabel控件只是字显示,控件背景色透明; 窗体客户区完全透明。 另外从网上看到的方法: setAttribute(Qt::WA_TranslucentBackground, true ); 试验的结果是类似于上面的方法,但有时候窗体会被一些杂色斑点填充,未找到原因。 2.窗口及其上面的控件都半透明: setWindowOpacity(0.7)试验效果:窗口及控件都半透明。 3.窗口整体不透明,局部透明:在Paint事件中使用Clear模式绘图。void TestWindow::paintEvent( QPaintEvent* )QPainter p(this );
p.fillRect( 10, 10, 300, 300, Qt::SolidPattern );试验效果:绘制区域全透明。

QT 半透明窗口和远程桌面

【中文标题】QT 半透明窗口和远程桌面【英文标题】:QT Translucent window and remote desktop 【发布时间】:2012-07-11 08:32:56 【问题描述】:

我正在为某些部分使用 QML 创建一个 Qt/C++ 应用程序。在 windows 下,我想使用 ExtendFrameIntoClientArea 的半透明窗口,如我的窗口类中的这个 sn-p 所示。

#ifdef Q_WS_WIN
    if ( QSysInfo::windowsVersion() == QSysInfo::WV_VISTA ||
         QSysInfo::windowsVersion() == QSysInfo::WV_WINDOWS7 )
    
        EnableBlurBehindWidget(this, true);
        ExtendFrameIntoClientArea(this);
    
#else

代码运行良好,但有一个例外。如果关闭透明窗口系统,背景会变黑,并且作为我的 UI 的一部分是透明的,它也会变暗。登录到运行应用程序的远程计算机时也会发生同样的事情,即使透明窗口系统立即重新初始化,背景也会保持黑色,直到再次执行上述代码。这在这张图片中得到了证明:Comparison of failed rendering (in background) and correct (in front).

问题是找到一个信号来连接重新初始化透明窗口,或者更好地检测窗口何时被透明绘制并相应地绘制 UI。也欢迎任何替代解决方案。

【问题讨论】:

【参考方案1】:

在对 Qt 和 MSDN Aero documentation 进行了深入研究之后,我想出了一个两步解决方案。通过覆盖主窗口的winEvent 方法,我能够接收到每次启用或禁用半透明窗口系统时触发的信号。

#define WM_DWMCOMPOSITIONCHANGED        0x031E

bool MainWindow::winEvent(MSG *message, long *result) 
    if ( message->message == WM_DWMCOMPOSITIONCHANGED ) 
        // window manager signaled change in composition
        return true;
    
    return false;

这让我非常接近,但它并没有告诉我 DWM 当前是否正在绘制透明窗口。通过使用dwmapi.dll,我能够找到一个完全可以做到这一点的方法,并且可以像下面这样访问它:

// QtDwmApi.cpp
extern "C"

    typedef HRESULT (WINAPI *t_DwmIsCompositionEnabled)(BOOL *pfEnabled);


bool DwmIsCompositionEnabled() 
    HMODULE shell;

    shell = LoadLibrary(L"dwmapi.dll");
    if (shell) 
        BOOL enabled;
        t_DwmIsCompositionEnabled is_composition_enabled = \
              reinterpret_cast<t_DwmIsCompositionEnabled>(
                  GetProcAddress (shell, "DwmIsCompositionEnabled")
                  );
        is_composition_enabled(&enabled);

        FreeLibrary (shell);

        if ( enabled ) 
            return true;
         else 
            return false;
        
    
    return false;

我的实现现在能够对 Aero 中的变化做出反应并相应地绘制 GUI。通过远程桌面登录时,窗口也会在可用的情况下使用透明度绘制。

【讨论】:

【参考方案2】:
The function should be written as follows to avoid the GPA failure

// QtDwmApi.cpp
extern "C"

    typedef HRESULT (WINAPI *t_DwmIsCompositionEnabled)(BOOL *pfEnabled);


bool DwmIsCompositionEnabled() 
    HMODULE shell;
    BOOL enabled=false;

    shell = LoadLibrary(L"dwmapi.dll");
    if (shell) 
        t_DwmIsCompositionEnabled is_composition_enabled = \
              reinterpret_cast<t_DwmIsCompositionEnabled>(
                  GetProcAddress (shell, "DwmIsCompositionEnabled")
                  );
        if (is_composition_enabled)
            is_composition_enabled(&enabled);

        FreeLibrary (shell);
   
    return enabled;

【讨论】:

以上是关于求助,关于Qt的窗口半透明,窗口上的空间不透明的主要内容,如果未能解决你的问题,请参考以下文章

qt 创建半透明异形窗口

Qt实现窗口半透明显示

Qt 子窗口设置为透明

unity部分模型半透明了怎么办

黑色半透明通知窗口叫啥名字?

htmlcss和js原生写一个模态弹出框,顺便解决父元素半透明子元素不透明效果