在 Windows 7 中,任务栏本身不是“应用程序窗口”,而是“应用程序用户模型”。例如,如果您有几个不同的应用程序实例正在运行,并且每个实例都有自己的图标,那么它们都将被分组在一个任务栏图标下。
默认情况下Windows 使用各种启发式方法来决定是否应该对不同的实例进行分同一组,在这种情况下,它决定由 Pythonw.exe 托管的所有内容都应该分组在 Pythonw.exe 的图标下。
正确的解决方案是让Pythonw.exe 告诉 Windows 它只是个托管程序,而不是主程序。也许未来的 Python 版本会做到这一点。
或者,您可以使用来自 Python api 调用 Windows 内置函数 来明确告诉 Windows 当前主进程的正确 AppUserModelID 是什么,
# set window
self.setWindowTitle("小i译读")
self.setWindowIcon(QtGui.QIcon('imgs/ai-48.png'))
# self.setWindowFlags(Qt.WindowTitleHint | Qt.CustomizeWindowHint |
# Qt.MSWindowsFixedSizeDialogHint)
self.setFixedSize(800, 560)
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID('CompanyName.ProductName.SubProduct.VersionInformation')
AppUserModelIDs的介绍( 详细请参阅AppUserModelIDs的 MSDN 文档)
Windows 7 及更高版本系统中任务栏广泛使用应用程序用户模型 ID (AppUserModelIDs) ,以将进程、文件和窗口与特定应用程序关联。 在某些情况下,依赖系统分配给进程的内部 AppUserModelID 就足够了。 但是,拥有多个进程的应用程序或在主机进程中运行的应用程序可能需要显式标识自身,以便它可以在单个任务栏按钮下将其他不同的窗口分组,并控制该应用程序跳转列表。
某些应用程序不声明显式 AppUserModelID。 它们是可选的。 在这种情况下,系统使用一系列启发法来分配内部 AppUserModelID。 但是,避免这些计算有性能优势,而显式 AppUserModelID 是保证完全用户体验的唯一方法。 因此,强烈建议设置显式 ID。 应用程序无法检索系统分配的 AppUserModelID。
如果应用程序使用显式 AppUserModelID,则还必须将相同的 AppUserModelID 分配给所有正在运行的窗口或进程、快捷方式和文件关联。 在通过 ICustomDestinationList自定义 AppUserModelID 跳转列表以及任何对 SHAddToRecentDocs的调用中,它也必须使用该 AppUserModelID。
应用程序必须以以下格式提供其 AppUserModelID。 它不能超过 128 个字符,并且不能包含空格。 每个部分都应为 pascal 大小写。
CompanyName.ProductName.SubProduct.VersionInformation
CompanyName``ProductName
应始终使用 和 ,而 和 部分是可选的,并且取决于 SubProduct
VersionInformation
应用程序的要求。 SubProduct
允许由多个子应用程序组成的主应用程序为每个子应用及其关联的窗口提供单独的任务栏按钮。 VersionInformation
允许应用程序的两个版本共存,同时被视为离散实体。 如果应用程序不应这样使用,应省略 ,以便升级后的版本可以使用与替换的版本相同的 VersionInformation
AppUserModelID。
关于设置AppUserModelID 的时机
If all windows in the process use the same AppUserModelID, set the AppUserModelID on the process though SetCurrentProcessExplicitAppUserModelID. An application must call SetCurrentProcessExplicitAppUserModelID to set its AppUserModelID during an application's initial startup routine before the application presents any UI, makes any manipulation of its Jump Lists, or makes (or causes the system to make) any call to SHAddToRecentDocs.