我想要创建一个GUI,没有Tkinter或任何其他库(最好是在Windows和CPython中)。
基本上,如果您进入Python及其库的文件,就可以找到库的函数。一个例子是randint库的random函数:
def randint(self, a, b):
"""Return random integer in range [a, b], including both end points.
"""
return self.randrange(a, b+1)现在,不用使用randint,我只需键入函数在我的程序中所做的事情。
这意味着Tkinter必须有类似的东西来创建GUI (尽管我找不到Tkinter的文件),这是一个虚构的示例:
def Tk(self, ...):
"""...
"""
...
(simple library like "os" or "sys").create_window(...)
...我希望使用create_window函数而不是Tkinter,我想要一些关于这些函数的文档。
我听说Tkinter直接与一些C类通信,如果是这样的话,我想知道如何直接从我的程序中进行,而不是使用Tkinter。我不在乎它是否更复杂、更不必要、更非pythonic,或者其他什么,我只需要创建一个GUI,而不需要任何GUI库。
发布于 2022-11-07 13:24:41
一个令人钦佩的目标!如果您这样做,我希望这是为了您自己的兴趣和开发,而不是任何严肃的应用程序,因为像tkinter这样的库是抽象的抽象,并且为您做了大量乏味的样板工作。在真实世界中,通常不适合自己做这样的工作,因为你会重犯几十年前Tcl开发人员犯的很多错误。然而,看看你如何去做这件事通常是很有趣的。
实际上,tkinter的源代码可以在GitHub上使用,您可以亲自阅读它。在CPython中,tkinter被实现为一系列python绑定这里和C模块这里。所有这些都是Tcl/Tk的接口,它们本身就是开源工具。它是几千行C和Python的代码,所以我恐怕不能很容易地总结它是如何工作的,但是在Windows上,它归结为对Windows的直接调用,函数包括RegisterClassW和CreateWindowW。
如果您愿意,可以使用ctypes直接从您自己的Python代码中与这些API进行接口--当然,这仍然是一个库,但是您将在一个比Tcl接口更基本的层次上进行交互。这个问题通过下面的代码片段提供了一个简单的起点:
import ctypes # An included library with Python install.
ctypes.windll.user32.MessageBoxA(0, "Your text", "Your title", 1)注意:根据这个问题的日期,它可能是一个Python2答案,所以在一个现代的ctypes.windll.user32.MessageBoxA(0, b"Your text", b"Your title", 1)实现中,调用可能是ctypes.windll.user32.MessageBoxA(0, b"Your text", b"Your title", 1)--我不运行ctypes.windll.user32.MessageBoxA(0, b"Your text", b"Your title", 1),所以我不知道。
您需要调用的函数都在微软网站的相关网页上有了详细的文档,所以您需要查找的是使用Windows进行图形编程的良好教程,然后将其转换到Python接口中。我自己也不能担保,但本教程看上去没问题。
这可能是因为你想要比这更低的级别,看看Windows在调用像MessageBoxA这样的函数时实际做了什么。我也很好奇,但是微软选择了保持API的封闭源代码,所以我们无法查看这个函数的源代码。如果您一定要知道,您将需要使用反向工程工具包来打开实现它的dll文件。根据你的管辖范围,这可能违反了当地的版权法,所以这个答案就到此为止。
发布于 2022-11-07 12:17:34
好吧..。这太复杂了,在windows上创建和操作应用程序的所有函数都是用C编写的,存储在windows 例如,如win32文档中所述,C语言就是这样做的上的例如,如win32文档中所述,C语言就是这样做的上的
这个程序需要通过C型转换成python,它将从python内部调用C代码,您将在python中编写C代码,这几乎是您用C编写的代码的4倍,它的工作速度将慢100倍,您必须在C、python和win32 api方面有很好的经验才能获得有用的应用程序.对于很多高级开发人员来说,这是可以提高的。
所以轨道是:
学习C ->学习win32 api ->学习python ->学习ctype ->学习python ABI ->制作一个简单的hello程序
用C编写代码更容易(也更快),然后将代码包装到python模块中,就像tkinter和wxwidget、QT以及几乎所有其他框架中所做的那样。
这是在32位python中如何操作的要点,但是它不能在64位python上工作,因为变量的类型在32位到64位的windows dlls之间发生了变化。https://gist.github.com/mouseroot/6128651
这是64位系统的另一个要点,它解决了类型问题。https://gist.github.com/syegulalp/7cf217677e893881a18d10020f2966e4
# Adapted for Python 3.6 + 64-bit Windows
from ctypes import *
from ctypes.wintypes import *
WNDPROCTYPE = WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)
WS_EX_APPWINDOW = 0x40000
WS_OVERLAPPEDWINDOW = 0xcf0000
WS_CAPTION = 0xc00000
SW_SHOWNORMAL = 1
SW_SHOW = 5
CS_HREDRAW = 2
CS_VREDRAW = 1
CW_USEDEFAULT = 0x80000000
WM_DESTROY = 2
WHITE_BRUSH = 0
class WNDCLASSEX(Structure):
_fields_ = [("cbSize", c_uint),
("style", c_uint),
("lpfnWndProc", WNDPROCTYPE),
("cbClsExtra", c_int),
("cbWndExtra", c_int),
("hInstance", HANDLE),
("hIcon", HANDLE),
("hCursor", HANDLE),
("hBrush", HANDLE),
("lpszMenuName", LPCWSTR),
("lpszClassName", LPCWSTR),
("hIconSm", HANDLE)]
user32 = ctypes.WinDLL('user32', use_last_error=True)
user32.DefWindowProcW.argtypes = [HWND, c_uint, WPARAM, LPARAM]
def PyWndProcedure(hWnd, Msg, wParam, lParam):
if Msg == WM_DESTROY:
user32.PostQuitMessage(0)
return 0
return user32.DefWindowProcW(hWnd, Msg, wParam, lParam)
def main():
WndProc = WNDPROCTYPE(PyWndProcedure)
hInst = windll.kernel32.GetModuleHandleW(0)
wclassName = u'My Python Win32 Class'
wname = u'My test window'
wndClass = WNDCLASSEX()
wndClass.cbSize = sizeof(WNDCLASSEX)
wndClass.style = CS_HREDRAW | CS_VREDRAW
wndClass.lpfnWndProc = WndProc
wndClass.cbClsExtra = 0
wndClass.cbWndExtra = 0
wndClass.hInstance = hInst
wndClass.hIcon = 0
wndClass.hCursor = 0
wndClass.hBrush = windll.gdi32.GetStockObject(WHITE_BRUSH)
wndClass.lpszMenuName = 0
wndClass.lpszClassName = wclassName
wndClass.hIconSm = 0
regRes = windll.user32.RegisterClassExW(byref(wndClass))
hWnd = windll.user32.CreateWindowExW(
0, wclassName, wname,
WS_OVERLAPPEDWINDOW | WS_CAPTION,
CW_USEDEFAULT, CW_USEDEFAULT,
300, 300, 0, 0, hInst, 0)
if not hWnd:
print('Failed to create window')
exit(0)
print('ShowWindow', windll.user32.ShowWindow(hWnd, SW_SHOW))
print('UpdateWindow', windll.user32.UpdateWindow(hWnd))
msg = MSG()
lpmsg = pointer(msg)
print('Entering message loop')
while windll.user32.GetMessageA(lpmsg, 0, 0, 0) != 0:
windll.user32.TranslateMessage(lpmsg)
windll.user32.DispatchMessageA(lpmsg)
print('done.')
if __name__ == "__main__":
print("Win32 Application in python")
main()在您的代码过于混乱和缓慢之后,您的代码只能在您的操作系统上工作,所以要将它移植到另一个操作系统仍然需要承受10倍的麻烦,所以最好使用库来处理这些东西。
https://stackoverflow.com/questions/74346199
复制相似问题