• tkinter使用xaml编写wpf


    引言

    在之前的一片文章tkinter使用wpf控件_Smart-Space的博客-CSDN博客中,我们实现了将wpf框架嵌入tkinter中。但是众所周知?,wpf可以通过xaml编写界面,这样能够极大地减少代码编写量,提高效率。

    但是,C#的xaml与cs结合是通过编译器实现的,而Python使用 .Net 只能够通过代码实现。不过,曲线救国的方法倒是一大堆。


    能够导入xaml的控件

    在wpf中,能够导入xaml的有:

    • Window

    • Frame

    • ContentControl及其父类和子类

    这些控件,都可以通过设置content属性,确定xaml内容。其中,Frame是通过Navigate方法实现页面跳转。

    介于Frame能够切换页面,因此我们选择Frame作为容器控件。


    xaml

    我们用如下xaml作为示例:

    <Page
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="Page1">
    <StackPanel Name="LayoutRoot">
    <Button Name="btn1"
            BorderBrush="Black" BorderThickness="1" 
     ClickMode="Hover">
      ClickMe1
    Button>
    
    <Calendar Margin="20" 
                SelectedDate="2/15/2009"
                DisplayDate="3/15/2009"
                DisplayDateStart="1/10/2009"
                DisplayDateEnd="4/18/2029"/>
    
    <TreeView>
      <TreeViewItem Header="Employee1">
        <TreeViewItem Header="Jesper"/>
        <TreeViewItem Header="Aaberg"/>
        <TreeViewItem Header="12345"/>
      TreeViewItem>
     <TreeViewItem Header="Employee2">
        <TreeViewItem Header="Dominik"/>
        <TreeViewItem Header="Paiha"/>
        <TreeViewItem Header="98765"/>
      TreeViewItem>
    TreeView>
    
    <RichTextBox Name="richTB">
      <FlowDocument>
        <Paragraph>
          <Run>Paragraph 1Run>
        Paragraph>
        <Paragraph>
          <Run>Paragraph 2Run>
        Paragraph>
        <Paragraph>
          <Run>Paragraph 3Run>
        Paragraph>
      FlowDocument>
    RichTextBox>
    
    
     StackPanel>
    Page>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    解析xaml

    作为 .Net 的一部分,wpf所要求的xaml读取结果当然不是Python自带的xml解析库的返回结果,而是基于System.Windows.MarkupXamlReader的解析结果。

    from System.Windows.Markup import XamlReader
    
    page = XamlReader.Parse(xaml)
    
    • 1
    • 2
    • 3

    注意,xaml解析需要在STA线程中执行。

    导入Frame

    这里直接使用Frame的Navigate就可以了。

    form.Navigate(page)
    
    • 1

    完整代码

    import clr
    clr.AddReference('System.Windows.Forms')
    clr.AddReference("PresentationFramework.Classic, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
    clr.AddReference("PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
    clr.AddReference('WindowsFormsIntegration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')#?
    clr.AddReference('System.Threading')
    from clr import System
    from System import Uri
    from System.Windows.Markup import XamlReader
    from System.Windows import LogicalTreeHelper
    from System.Windows.Controls import Frame as wpfFrame,Button as wpfButton
    from System.Windows.Forms.Integration import ElementHost
    from System.Windows.Forms import Control
    from System.Threading import Thread,ApartmentState,ThreadStart
    from tkinter import Frame,Tk
    from tkinter import ttk
    import ctypes
    user32=ctypes.windll.user32
    from tkwpf import tkWPF
    
    
    xaml='''
    
    
    
    
    
    
    
      
        
        
        
      
     
        
        
        
      
    
    
    
      
        
          Paragraph 1
        
        
          Paragraph 2
        
        
          Paragraph 3
        
      
    
    
    
     
    
    '''
    
    
    def STAMain():
        global media
        try:
            a=Tk()
            a.geometry('500x500')
            f=tkWPF(a)
            f.pack(fill='both',expand=True)
    
            form=wpfFrame()
            page = XamlReader.Parse(xaml)
            form.Navigate(page)
            f.control(form)
    
            Button1 = LogicalTreeHelper.FindLogicalNode(page, "btn1")
            print(Button1)
    
            a.mainloop()
        except Exception as err:
            print(err)
    
    def main():
        t = Thread(ThreadStart(STAMain))
        t.ApartmentState = ApartmentState.STA
        t.Start()
        t.Join()
    
    if __name__ == "__main__":
        main()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    效果:

    在这里插入图片描述


    结语

    因为一些原因,我没有将其写成类,只是做了一个范例而已。有需要的可以自行更改源码。

    🔆tkinter创新🔆

  • 相关阅读:
    不容易解的题10.5
    快手一面:优化MySQL索引创建,减轻线上服务影响
    IDEA启动时报Failed to create JVM错误的解决
    二维码智慧门牌管理系统升级,异常门牌聚合解决方案助力高效管理
    iOS代码混淆工具推荐:IPA Guard详细介绍
    广州蓝景分享—前端开发JavaScript中的Array对象与其他数组
    Map集合详细讲解
    Vue3基础(26)___defineProps、defineEmits、defineExpose组件通信
    haproxy
    运营人看双十一,学营销技巧
  • 原文地址:https://blog.csdn.net/tinga_kilin/article/details/125949091