使用Python创建HUD

时间:2019-03-03 20:21:34

标签: python winapi pyqt4

我正在尝试使用Python为第三方应用程序编写HUD。

当第三方应用程序移动时,我已经能够确保我的HUD遵循第三方应用程序,但是我难以确保HUD始终出现在第三方应用程序的顶部,而在HUD消失时却消失了。最小化或其他应用程序出现在前台时。

我已经尝试了Window API的某些功能(SetWindowPosBringWindowToTopSetForegroundWindow),但这些功能都没有给我带来预期的结果:HUD始终落后于第三方应用。

这是一个简单的代码示例来说明我的问题:

/// <summary>
/// ManageController - Controller for Managing Admin Stuff
/// </summary>
[Area("admin")]
[Route("admin/[controller]")]
[Authorize(Policy = "RequireAdminRole")]
public class ManageController : Controller
{
    /// <summary>
    /// Private instance of the <see cref="EmailViewModel"/> class
    /// </summary>
    private EmailViewModel emailViewModel;
    private SmtpClient smtpClient;

    /// <summary>
    /// Initializes a new instance of the <see cref="ManageController"/> class
    /// </summary>
    /// <param name="smtpClient"></param>
    public ManageController(SmtpClient smtpClient)
    {
        this.smtpClient = smtpClient;
    }


    /// <summary>
    /// HomePage for the admin management area
    /// </summary>
    /// <returns></returns>
    public IActionResult Index()
    {
        return View();
    }
}

我还尝试使用SetParent将第三方应用程序设置为HUD的父级,但是这样做时,我的HUD根本不显示。

您是否有任何使用Window API或其他工具使其工作的建议?

2 个答案:

答案 0 :(得分:0)

尝试一下:

# ... 
def launchHud(self):
    window_handle = user32.FindWindowW(0,WINDOW_NAME)
    if window_handle != 0 :
        self.hud = Hud(window_handle)

        self.hud.setWindowFlags(self.windowFlags()     |     # <---
                                Qt.FramelessWindowHint |     # <---
                                Qt.WindowStaysOnTopHint)     # <---
        self.hud.show()                                      # <--- !!!
# ...

答案 1 :(得分:0)

我最终通过将HUD父类设置为SetParent而不是QMainWindow,并通过QLabel来确保我的HUD始终保持在给定第三方应用程序的顶部。删除对setWindowOpacity的呼叫。以下代码对我有用:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

import ctypes
import ctypes.wintypes

user32 =  ctypes.windll.user32
HUD_WIDTH = 100
HUD_HEIGHT = 50 
WINDOW_NAME = "Window name" #Replace this by the name of an opened window 

class Hud(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.hwnd = self.winId().__int__()


    def initUI(self):
        self.setWindowFlags(Qt.FramelessWindowHint)   
        self.resize(HUD_WIDTH,HUD_HEIGHT)   
        self.textArea = QLabel()
        self.setCentralWidget(self.textArea);  
        self.setStyleSheet("background-color: rgb(0, 0, 0);color: rgb(255,255,255);")
        self.textArea.setText("Hello")
        self.textArea.setAlignment(Qt.AlignCenter)
        self.show()


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow,self).__init__()
        self.initUI()
    def initUI(self):
        self.launch_hud_button = QPushButton("Launch HUD",self)
        self.launch_hud_button.clicked.connect(self.launchHud)
        self.show()
    def launchHud(self):
        window_handle = user32.FindWindowW(0,WINDOW_NAME)
        if window_handle != 0 :
            self.hud = Hud()
            user32.SetParent(self.hud.hwnd,window_handle)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    sys.exit(app.exec_())  

如果有人知道QMainWindowSetParent一起工作的原因,而不是像QLabel这样的Qt类,或者为什么修改窗口不透明度会导致不可见的HUD,我会非常感兴趣。对SetParent的调用不会返回0,因此我假设HUD实际上设置为我的第三方应用程序的子级,但是被绘制为完全透明的。)