qml demo分析(text-字体展示)

本文介绍了使用QML进行文本展示的各种技巧,包括淡出效果、字体样式调整、系统字体展示、跑马灯效果、图文混排及自定义文本布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  上一篇文章分析了一个小游戏,使用qml编写界面+js进行复杂逻辑控制,算是一个比较完整的qml示例代码了,今天就不那么继续变态啦,来看一个简单的字体示例程序吧,该示例代码比较简单,主要是展示了几个简单的使用场景,下边我将逐个进行分析

1、淡出

  如图1所示是一个文本淡出并伴随字母间距增大的效果,该组件使用了两个序列动画,一个用于将字母间距放大,另一个用于改变文字透明度

图1 淡出

  代码如下所示

 1 //Hello world字样  3000ms淡出并伴随着字母间距增大  之后文本框位置瞬间重置 进行下一个3000淡出
 2 import QtQuick 2.0
 3 
 4 Rectangle {
 5     id: screen
 6 
 7     width: 320; height: 480
 8     color: "black"
 9 
10     Item {//文本框
11         id: container
12         x: screen.width / 2; y: screen.height / 2
13 
14         Text {
15             id: text
16             anchors.centerIn: parent
17             color: "white"
18             text: "Hello world!"
19             font.pixelSize: 32
20 
21 //! [letterspacing]
22             SequentialAnimation on font.letterSpacing {//字母间距
23                 loops: Animation.Infinite;//无限循环
24                 NumberAnimation { from: 0; to: 50; easing.type: Easing.InQuad; duration: 3000 }//3000ms将字母间距从0变到50
25                 ScriptAction {//动画结束后  使用脚本动作  重置该文本框位置
26                     script: {
27                         container.y = (screen.height / 4) + (Math.random() * screen.height / 2)
28                         container.x = (screen.width / 4) + (Math.random() * screen.width / 2)
29                     }
30                 }
31             }
32 //! [letterspacing]
33 
34             SequentialAnimation on opacity {//应用于透明度上的序列动画
35                 loops: Animation.Infinite;//无限循环
36                 NumberAnimation { from: 1; to: 0; duration: 2600 }//淡出效果
37                 PauseAnimation { duration: 400 }//暂停400ms  加上该动画之前动画2600ms 总共3000ms  同letterSpacing序列动画刚好构成一个并行动画
38             }
39         }
40     }
41 }

2、字体样式

  qml有内置FontLoader可以加载系统字体、本地字体和远端字体,效果如图2所示

图2 字体样式

  改变字体样式和字体显示风格都使用了font属性组

 1 import QtQuick 2.0
 2 
 3 Rectangle {
 4     property string myText: "The quick brown fox jumps over the lazy dog."//各Text将显示文本
 5 
 6     width: 320; height: 480
 7     color: "steelblue"
 8 
 9 //! [fontloader]
10     FontLoader { id: fixedFont; name: "Courier" }//加载系统字体Courier
11 //! [fontloader]
12 //! [fontloaderlocal]
13     FontLoader { id: localFont; source: "content/fonts/tarzeau_ocr_a.ttf" }//加载本地字体
14 //! [fontloaderlocal]
15 //! [fontloaderremote]
16     FontLoader { id: webFont; source: "http://www.princexml.com/fonts/steffmann/Starburst.ttf" }//加载远端字体
17 //! [fontloaderremote]
18 
19     Column {
20         anchors { fill: parent; leftMargin: 10; rightMargin: 10; topMargin: 10 }
21         spacing: 15
22 
23         Text {
24             text: myText//指定文本显示内容
25             color: "lightsteelblue"//指定文本颜色
26             width: parent.width
27             wrapMode: Text.WordWrap//一行显示不下时 换行模式  按字换行  保证换行时一个单词不会被显示在两行
28 //! [name]
29             font.family: "Times"//通过字体名称指定字体  
30 //! [name]
31             font.pixelSize: 20//字体像素大小
32         }
33         Text {
34             text: myText
35             color: "lightsteelblue"
36             width: parent.width
37             wrapMode: Text.WordWrap
38             horizontalAlignment: Text.AlignHCenter//水平方向居中
39             font { //通过font指定字体各项属性 也可以通过font.attribute来单个设置
40                 family: "Times"; 
41                 pixelSize: 20; 
42                 capitalization: Font.AllUppercase//设置字母都大写
43             }
44         }
45         Text {
46             text: myText
47             color: "lightsteelblue"
48             width: parent.width
49             horizontalAlignment: Text.AlignRight//文本右对齐
50             wrapMode: Text.WordWrap
51             font { 
52                 family: fixedFont.name; //通过字体加载器设置字体
53                 pixelSize: 20; 
54                 weight: Font.Bold; //字体加粗
55                 capitalization: Font.AllLowercase//设置字母都小写
56             }
57         }
58         Text {
59             text: myText
60             color: "lightsteelblue"
61             width: parent.width
62             wrapMode: Text.WordWrap
63             font { 
64                 family: fixedFont.name; 
65                 pixelSize: 20; 
66                 italic: true; 
67                 capitalization: Font.SmallCaps//以小写字母的大小写大写字母  首字母依然是正常大写
68             }
69         }
70         Text {
71             text: myText
72             color: "lightsteelblue"
73             width: parent.width
74             wrapMode: Text.WordWrap
75             font { 
76                 family: localFont.name; 
77                 pixelSize: 20; 
78                 capitalization: Font.Capitalize//每个单词的首字母大写
79             }
80         }
81         Text {
82             text: {
83                 if (webFont.status == FontLoader.Ready) myText
84                 else if (webFont.status == FontLoader.Loading) "Loading..."
85                 else if (webFont.status == FontLoader.Error) "Error loading font"
86             }
87             color: "lightsteelblue"
88             width: parent.width
89             wrapMode: Text.WordWrap
90             font.family: webFont.name;//设置远端字体名称
91             font.pixelSize: 20
92         }
93     }
94 }

3、系统字体

图3 系统字体

   如图3所示,使用了ListView展示了当前系统支持的所有字体,文本项所使用的字体样式就是文本内容,代码如下

 1 //展示当前系统所有字体
 2 import QtQuick 2.0
 3 
 4 Rectangle {
 5     width: 320; height: 480; color: "steelblue"
 6 
 7     ListView {
 8         anchors.fill: parent
 9 //! [model]
10         model: Qt.fontFamilies()//数据源是所有的qt字体
11 //! [model]
12 
13         delegate: Item {
14             height: 40; width: ListView.view.width
15             Text {
16                 anchors.centerIn: parent
17                 text: modelData//文本内容显示字体名称
18 //! [delegate]
19                 font.family: modelData//设置字体名称
20 //! [delegate]
21                 font.pixelSize: 20//字体像素大小
22                 color: "white"//字体颜色
23             }
24         }
25     }
26 }

4、跑马灯

  示例代码中banner.qml组件实现了跑马灯效果,不过个人感觉效果不是特别好,因此这里就不细说,如果感兴趣的同学可自行到Qt5.7.0_vs2013\Examples\Qt-5.7\quick\text目录下查找,该文件代码量比较少

5、图文混用

  qml对css支持的相对来说还可以,css已经发展到3.0版本,具体qml友好的支持到哪一版本感兴趣的同学可自行上网上查找

图4 图文混合

  如图4所示是简单的图文混用,其实代码也比较简单,主要还是使用了web技术中的一些关键字,比如<b>:加粗,<img>:远端图片等。代码如下

 1 import QtQuick 2.0
 2 
 3 Rectangle {
 4     id: main
 5     width: 320; height: 480
 6     focus: true
 7     color: "#dedede"
 8 
 9     property var hAlign: Text.AlignLeft
10 
11     Flickable {//可滑动区域
12         anchors.fill: parent
13         contentWidth: parent.width
14         contentHeight: col.height + 20
15 
16         Column {
17             id: col
18             x: 10; y: 10
19             spacing: 20
20             width: parent.width - 20
21 
22             TextWithImage {
23                 text: "This is a <b>happy</b> face<img src=\"images/face-smile.png\">"//谁用css语法  设置happy字体加粗  并使用img关键字导入图片
24             }
25             TextWithImage {
26                 text: "This is a <b>very<img src=\"images/face-smile-big.png\" align=\"middle\"/>happy</b> face vertically aligned in the middle."//使用middle属性将图片置于中间位置
27             }
28             TextWithImage {
29                 text: "This is a tiny<img src=\"images/face-smile.png\" width=\"15\" height=\"15\">happy face."//使用width和height属性设置图片大小
30             }
31             TextWithImage {
32                 text: "This is a<img src=\"images/starfish_2.png\" width=\"50\" height=\"50\" align=\"top\">aligned to the top and a<img src=\"images/heart200.png\" width=\"50\" height=\"50\">aligned to the bottom."
33             }
34             TextWithImage {//连续导入3张图片 并设置其大小 位置居中
35                 text: "Qt logos<img src=\"images/qtlogo.png\" width=\"55\" height=\"60\" align=\"middle\"><img src=\"images/qtlogo.png\" width=\"37\" height=\"40\" align=\"middle\"><img src=\"images/qtlogo.png\" width=\"18\" height=\"20\" align=\"middle\">aligned in the middle with different sizes."
36             }
37             TextWithImage {
38                 text: "Some hearts<img src=\"images/heart200.png\" width=\"20\" height=\"20\" align=\"bottom\"><img src=\"images/heart200.png\" width=\"30\" height=\"30\" align=\"bottom\"> <img src=\"images/heart200.png\" width=\"40\" height=\"40\"><img src=\"images/heart200.png\" width=\"50\" height=\"50\" align=\"bottom\">with different sizes."
39             }
40             TextWithImage {//从远端加载图片
41                 text: "Resized image<img width=\"48\" height=\"48\" align=\"middle\" src=\"http://qt-project.org/images/qt13a/Qt-logo.png\">from the internet."
42             }
43             TextWithImage {
44                 text: "Image<img align=\"middle\" src=\"http://qt-project.org/images/qt13a/Qt-logo.png\">from the internet."
45             }
46             TextWithImage {
47                 height: 120
48                 verticalAlignment: Text.AlignVCenter
49                 text: "This is a <b>happy</b> face<img src=\"images/face-smile.png\"> with an explicit height."
50             }
51         }
52     }
53 
54     Keys.onUpPressed: main.hAlign = Text.AlignHCenter//水平居中
55     Keys.onLeftPressed: main.hAlign = Text.AlignLeft//水平居左
56     Keys.onRightPressed: main.hAlign = Text.AlignRight//水平居右
57 }

  如上代码54-56行,对键盘事件进行了简单处理,向上键:文本水平居中,向左键:水平居左,向右键:水平居中

6、文本布局

  之前一直用QTextEdit做文本显示功能,一直很羡慕html的文本布局功能,现在不用担心了,qml也可以在文本布局时做自己想做的一些事情,主要还是处理lineLaidOut信号,如图5所示,该文本显示在窗口左半侧进行展示,当展示不下时,从右半侧窗口开始展示

图5 Text自定义布局

  当窗口进行放大缩小时,这个灵活布局才能更有好多的展示,感兴趣的同学可以自己运行qt示例,要实现这个友好的功能其实代码量很少,代码如下所示

 1 //复杂文本显示
 2 import QtQuick 2.0
 3 
 4 Rectangle {
 5     id: main
 6     width: 320; height: 480
 7     focus: true
 8 
 9     property real offset: 0
10     property real margin: 8
11 
12     Text {
13         id: myText
14         anchors.fill: parent
15         anchors.margins: 10
16         wrapMode: Text.WordWrap
17         font.family: "Times New Roman"
18         font.pixelSize: 14
19         textFormat: Text.StyledText
20         horizontalAlignment: Text.AlignJustify
21         
22         //css关键字 <a  <br <ul <ol <li  <p
23         text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at ante dui <a href=\"http://www.digia.com\">www.digia.com</a>.<br/>Curabitur ante est, pulvinar quis adipiscing a, iaculis id ipsum. Nunc blandit condimentum odio vel egestas.<br><ul type=\"bullet\"><li>Coffee<ol type=\"a\"><li>Espresso<li>Cappuccino<li>Latte</ol><li>Juice<ol type=\"1\"><li>Orange</li><li>Apple</li><li>Pineapple</li><li>Tomato</li></ol></li></ul><p><font color=\"#434343\"><i>Proin consectetur <b>sapien</b> in ipsum lacinia sit amet mattis orci interdum. Quisque vitae accumsan lectus. Ut nisi turpis, sollicitudin ut dignissim id, fermentum ac est. Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus, viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta eu. Quisque vitae accumsan lectus. Ut nisi turpis, sollicitudin ut dignissim id, fermentum ac est. Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci."
24 
25 //! [layout]
26         onLineLaidOut: {
27             line.width = width / 2  - (margin)//每一行的宽度只有当前根窗口宽度一半
28 
29             if (line.y + line.height >= height) {//当文字显示越过窗口底部时
30                 line.y -= height - margin//y值将去窗口高度
31                 line.x = width / 2 + margin//x值向右移动根窗口宽度一半    即从由半侧窗口显示剩余文本
32             }
33         }
34 //! [layout]
35     }
36 }

 

好啦。。。qml简单的文本展示就这么些了,其实应该还有很多,只是这个示例程序就这么些,那我们暂时也就说这么多吧。

转载于:https://www.cnblogs.com/swarmbees/p/6565415.html

<think>我们正在处理一个关于QML TableView的需求,用户希望有一个完整的示例代码,其中表头和表尾固定显示。根据引用[1][2][3][4],我们知道Qt QML的TableView组件可以用于展示表格数据,并且可以通过一些属性来实现排序、过滤等功能。但是,固定表头和表尾需要一些额外的处理。 在QML中,TableView本身并不直接提供固定表头和表尾的功能。但是,我们可以通过组合多个视图来实现:一个视图用于显示表头,一个视图用于显示表格主体(可滚动),一个视图用于显示表尾。为了实现表头固定,我们可以将表头视图放在主体视图的上方,并且当主体视图滚动时,通过绑定确保表头视图不滚动。同样,表尾视图放在主体视图的下方,并且固定不动。 然而,引用[3]提到了使用`syncView`属性来同步表头视图和主体视图,这可以用于列的对齐。我们可以利用这个属性来同步列宽。 设计思路: 1. 使用一个主TableView作为主体(可滚动区域)。 2. 使用一个单独的TableView作为表头,将其放在主体TableView的上方,并且将其列宽与主体TableView同步(使用syncView属性)。 3. 使用一个单独的TableView或一个Row组件作为表尾,放在主体TableView的下方,同样同步列宽。 但是,注意表尾通常只有一行,并且不需要滚动。我们可以用一个简单的Row组件来模拟,或者用另一个TableView(但只有一行)。 由于表头和表尾需要与主体视图的列对齐,我们需要确保它们的列宽一致。我们可以通过设置表头和表尾的TableView的syncView属性指向主体TableView。 另外,引用[3]提到了在水平标题栏(表头)中使用syncView属性,这样就可以将表头与主体表格绑定,实现列宽同步。 下面是一个完整的示例代码,包括固定表头和表尾: 注意:我们使用QtQuick 2.x和QtQuick.Controls 2.x。这里假设使用较新的版本(如Qt 5.15或Qt6)。 步骤: 1. 定义数据模型(这里使用ListModel作为示例)。 2. 创建主体TableView,并设置其行和列。 3. 创建表头TableView,设置syncView为主体TableView,并只显示一行(即表头行)。 4. 创建表尾(这里用Repeater和Row来模拟,因为表尾通常是一些汇总信息,可能不是表格形式,但为了列对齐,我们可以按照列的宽度来布局)。 但是,表尾的固定可能需要将表尾放在一个不会滚动的区域,并且与主体表格的列宽同步。我们可以通过获取主体表格的列宽信息来设置表尾中每个单元格的宽度。 然而,更简单的方式是使用另一个TableView作为表尾,设置其只有一行,并且syncView指向主体表格,这样列宽就会同步。 但是,由于表头和表尾都需要固定,我们将它们放在一个Flickable的外部,而主体表格放在一个Flickable内部(实际上TableView内部已经有一个Flickable,所以我们需要确保表头和表尾不随主体滚动)。 由于TableView内部已经处理了滚动,我们无法直接通过外部Flickable来控制。因此,我们采用两个独立的TableView作为表头和表尾,并确保它们与主体表格的列宽同步,同时将表头和表尾放在主体表格的外部,不包含在主体表格的滚动区域内。 具体布局: 整个组件结构: - 一个Column布局,包含: 1. 表头(HeaderView,是一个TableView,但只显示一行,并且不可滚动) 2. 主体(BodyView,是一个TableView,可滚动) 3. 表尾(FooterView,是一个TableView,只显示一行,不可滚动) 但是,当主体部分滚动时,表头和表尾需要保持不动。而列宽同步通过syncView属性实现。 注意:表头和表尾的模型需要单独定义,因为表头通常只有一行(列标题),表尾也只有一行(汇总行)。 示例代码: 我们将创建一个包含表头、主体和表尾的表格,其中表头和表尾固定,主体可滚动。 由于代码较长,我们将分步骤编写。 注意:在QML中,TableView的样式和委托可以自定义。 我们假设表头模型和表尾模型都是只有一行的模型。 以下是完整的示例代码:</think>以下是一个使用 QML 实现固定表头和表尾的 TableView 完整示例代码,基于 Qt 6.5+ 版本: ```qml import QtQuick import QtQuick.Controls import QtQuick.Layouts ApplicationWindow { width: 600 height: 400 visible: true // 数据模型 ListModel { id: tableModel ListElement { name: "Alice"; age: 28; department: "HR" } ListElement { name: "Bob"; age: 32; department: "Engineering" } ListElement { name: "Charlie"; age: 25; department: "Marketing" } ListElement { name: "Diana"; age: 40; department: "Finance" } } ColumnLayout { anchors.fill: parent spacing: 0 // 固定表头 HorizontalHeaderView { id: headerView syncView: tableView Layout.fillWidth: true height: 40 delegate: Rectangle { color: "#e0e0e0" border.color: "#a0a0a0" Text { text: model.display anchors.centerIn: parent font.bold: true } } } // 表格主体(可滚动区域) TableView { id: tableView model: tableModel clip: true Layout.fillWidth: true Layout.fillHeight: true // 列定义 columnWidthProvider: function(column) { return column === 0 ? 200 : 150 } // 行委托 delegate: Rectangle { color: row % 2 ? "#f5f5f5" : "white" border.color: "#e0e0e0" implicitHeight: 40 TextInput { text: display anchors.fill: parent anchors.margins: 8 verticalAlignment: Text.AlignVCenter selectByMouse: true } } } // 固定表尾 HorizontalHeaderView { id: footerView syncView: tableView Layout.fillWidth: true height: 40 visible: true delegate: Rectangle { color: "#d0e0ff" border.color: "#a0a0a0" Text { text: { if (column === 0) return "总计" if (column === 1) { let total = 0 for (let i = 0; i < tableModel.count; i++) { total += tableModel.get(i).age } return total } return "" } anchors.centerIn: parent font.bold: true } } } } } ``` ### 关键实现说明: 1. **固定表头**: - 使用 `HorizontalHeaderView` 组件作为表头 - 通过 `syncView: tableView` 实现与主体表格列同步[^2] - 设置固定高度 (`height: 40`) 2. **固定表尾**: - 同样使用 `HorizontalHeaderView` 组件 - 添加自定义计算逻辑(如年龄总和) - 使用不同背景色区分 (`color: "#d0e0ff"`) 3. **表格主体**: - 使用 `TableView` 组件 - `columnWidthProvider` 定义列宽 - 斑马纹效果通过行号奇偶判断实现 4. **布局管理**: - 使用 `ColumnLayout` 垂直排列三个部分 - `Layout.fillWidth/Height` 确保正确填充空间 - `spacing: 0` 消除组件间距 ### 注意事项: 1. **列对齐问题**: - 如果出现列不对齐,检查是否所有组件都设置了 `syncView` 属性[^3] - 确保表头/表尾与主体表格的列定义一致 2. **性能优化**: - 大数据集时建议使用 `TableView` 的异步加载模式 - 启用 `clip: true` 防止渲染区域外内容 3. **编辑功能**: - 当前使用 `TextInput` 支持单元格编辑 - 若需禁用编辑,可替换为 `Text` 组件[^3] 4. **样式定制**: - 通过修改 `delegate` 中的颜色/字体属性自定义外观 - 添加 `MouseArea` 可实现行选择功能 > 此实现利用了 Qt 6 新增的 `HorizontalHeaderView` 组件,相比传统方法更简洁[^4]。如需兼容旧版本 Qt,可采用 `ListView` + 定位绑定的替代方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值