简体   繁体   English

如何 select 窗口客户区的特定部分显示在 Python/PyQt5/PySide2/Tkinter 任务栏中的窗口缩略图中?

[英]how to select a particlular portion of a window's client area to display in window's thumbnail in the taskbar in Python/PyQt5/PySide2/Tkinter?

I want to set a particular portion(like only a frame or widget) of my application window to taskbar thumbnail.I found one windows API that is ITaskbarList3::SetThumbnailClip here but this is in C++.I want to do this in python.However PyQt5 contains one class that is Qt Windows Extras which doesnot include this function.I have also found something that show one example here .This link might help you to solve easily. I want to set a particular portion(like only a frame or widget) of my application window to taskbar thumbnail.I found one windows API that is ITaskbarList3::SetThumbnailClip here but this is in C++.I want to do this in python.However PyQt5 contains one class that is Qt Windows Extras which doesnot include this function.I have also found something that show one example here .This link might help you to solve easily. As I am a beginner,i dont know how to do that properly.由于我是初学者,我不知道如何正确地做到这一点。

Edit And Fix Me:-编辑修复我:-

I have tried the second link provided in the question,I have installed comptypes Module through PIP and i have copied taskbarlib.tlb file from github as i have not Windos SDK installed to generate this file as said in the answer here .我已经尝试了问题中提供的第二个链接,我已经通过PIP安装了comptypes模块,并且我已经从github复制了 taskbarlib.tlb文件,因为我没有安装 Windows ZF20E3C5E54C0AB3D3765D660B3F8 的答案来生成文件。

Here is my code.这是我的代码。

from PyQt5.QtWidgets import *
import sys
##########----IMPORTING Comtypes module
import comtypes.client as cc
cc.GetModule('taskbarlib.tlb')
import comtypes.gen.TaskbarLib as tb
taskbar=cc.CreateObject('{56FDF344-FD6D-11d0-958A-006097C9A090}',interface=tb.ITaskbarList3)
##################
class MainUiClass(QMainWindow):
     def __init__(self,parent=None):
        super(MainUiClass,self).__init__(parent)
        self.resize(600,400)
        self.frame=QFrame(self)
        self.frame.setGeometry(100,100,400,200)
        self.frame.setStyleSheet('background:blue')
if __name__=='__main__':
      app=QApplication(sys.argv)
      GUI=MainUiClass()
      GUI.show()
      taskbar.HrInit()
      ####--This is just to check its working or not by setting a tasbar progress bar value
      taskbar.SetProgressValue(GUI.winId(),40,100)
      ##########################################
      ##########This is a method to get the LP_RECT instace as per Microsoft API doc.Using Ctypes and got ctypes.wintypes.RECT object  
      from ctypes import POINTER, WINFUNCTYPE, windll, WinError
      from ctypes.wintypes import BOOL, HWND, RECT
      prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
      paramflags = (1, "hwnd"), (2, "lprect")
      GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)
      newrect=GetWindowRect(int(GUI.frame.winId()))
      print(newrect)
      taskbar.SetThumbnailClip(int(GUI.winId()),newrect)
      sys.exit(app.exec_())

i have got that method to find LP_RECT instance form Ctypes module Doc.我有这种方法可以从Ctypes 模块文档中找到 LP_RECT 实例。 here 这里在此处输入图像描述 But I have a problem I want to set the frame(blue colored) into taskbar and i got this但我有一个问题,我想将框架(蓝色)设置到任务栏中,我得到了这个在此处输入图像描述

Look at the screenshot,the taskbarprogress value that i have set for testing, works fine,but the thumbnail part is just Unexpected .查看屏幕截图,我为测试设置的任务栏进度值工作正常,但缩略图部分只是Unexpected Can anyone help me to fix this?谁能帮我解决这个问题?

Thanks to Eliya Duskwight to help me slove this.感谢Eliya Duskwight帮助我解决这个问题。 I have corrected my code.我已经更正了我的代码。

This is For PyQt5 And PySide2 as well as Tkinter这适用于PyQt5 和 PySide2以及Tkinter

Here is mycode for PyQt5/PySide2这是 PyQt5/PySide2 的 mycode

from PyQt5.QtWidgets import *          ###For PyQt5
from PySide2.QtWidgets import *        ###For PySide2
import sys
###Most Important Part###
import comtypes.client as cc
cc.GetModule('taskbarlib.tlb')
import comtypes.gen.TaskbarLib as tb
taskbar=cc.CreateObject('{56FDF344-FD6D-11d0-958A-006097C9A090}',interface=tb.ITaskbarList3)
class MainUiClass(QMainWindow):
   def __init__(self,parent=None):
        super(MainUiClass,self).__init__(parent)
        self.resize(600,400)
        self.setStyleSheet('background:red')
        self.frame=QFrame(self)
        self.frame.setGeometry(100,100,400,200)
        self.frame.setStyleSheet('background:blue')
if __name__=='__main__':
      app=QApplication(sys.argv)
      GUI=MainUiClass()
      GUI.show()
      taskbar.HrInit()
      ##You need to find "hwnd" of your Window and "LP_RECT" instance of Geometry you want, as per Microsoft API Doc. using Ctypes
      from ctypes.wintypes import  RECT,PRECT 
      newrect=PRECT(RECT(0,0,600,400))
      taskbar.SetThumbnailClip(int(GUI.winId()),PRECT(RECT(0,0,600,400)))

Not only you can use this API for thumbnailclip but also for various functions like ThumbnailToolTip,Taskbar Progress,Taskbar Progressbar,Taskbar Overlay Icon,Adding Buttons etc .You need to read the interface here您不仅可以将此API用于缩略图剪辑,还可以用于缩略图工具提示、任务栏进度、任务栏进度条、任务栏覆盖图标、添加按钮等各种功能。您需要在此处阅读界面

>>> For Tkinter >>>适用于Tkinter

from tkinter import *
from ctypes import windll
from ctypes.wintypes import  RECT,PRECT
###Most Important Part###
import comtypes.client as cc
cc.GetModule('taskbarlib.tlb')
import comtypes.gen.TaskbarLib as tb
taskbar=cc.CreateObject('{56FDF344-FD6D-11d0-958A-006097C9A090}',interface=tb.ITaskbarList3)
root=Tk()
root.geometry("400x300")
root.config(bg="red")
frame=Frame(root,bg='blue',width=200,height=100)
frame.place(x=100,y=100)

def setThumbnail():
   hwnd = windll.user32.GetParent(root.winfo_id())
   print(hwnd)
   taskbar.HrInit()
   taskbar.SetThumbnailClip(hwnd,PRECT(RECT(0,0,60,60)))#Geometry You Want To Set
root.after(1000,setThumbnail)   
root.mainloop()

I found root.winfo_id() doesnot give the correct hwnd .I dont know why?So i used hwnd = windll.user32.GetParent(root.winfo_id()) to find the correct one.我发现root.winfo_id()没有给出正确的hwnd 。我不知道为什么?所以我用hwnd = windll.user32.GetParent(root.winfo_id())来找到正确的。

Note: This works after the window is visible,So for PyQt5/PySide2 ,it should be called after calling window.show() & For Tkinter ,it should be called after sometime,for that you can use root.after() Or Some event, and You should have that taskbarlib.tlb file pasted in your module folder or in your script folder.You can also generate it using Windows SDK or IDL compiler .Then install comtypes module to work.And remember注意:这在 window 可见后有效,因此对于PyQt5/PySide2 ,应在调用window.show()后调用它 & 对于Tkinter或某些时候可以使用root。事件,并且您应该将该taskbarlib.tlb 文件粘贴到您的模块文件夹或脚本文件夹中。您也可以使用Windows SDK 或 IDL 编译器生成它。然后安装comtypes模块以工作。记住

The return of S_OK,means the return of SetThumbnailClip() is 0 always.so anything except 0 is a error.This might crash the application.And As per Microsoft API,the Minimum Required OS is Windows7. S_OK 的返回,意味着 SetThumbnailClip() 的返回始终为 0。因此,除 0 之外的任何内容都是错误。这可能会使应用程序崩溃。并且根据 Microsoft API,最低要求的操作系统是 Windows7。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM