Python游戏引擎开发(四):TextField文本类

上一章我们主要介绍了显示对象和如何显示图片。本章来讲述显示文本。

以下是本系列教程前几章地址,在阅读本篇正文之前,请务必阅读前几章内容。

Python游戏引擎开发(一):序

Python游戏引擎开发(二):创建窗口以及重绘界面

Python游戏引擎开发(三):显示图片

文本类TextField

使用过flash的朋友都知道,这个类其实不光是显示文本用的,还可以用于显示输入框。我这里就只实现一些基础实用的功能,以后有时间了慢慢拓展。和上一章一样,TextField是一个显示对象,继承自DisplayObject。以下是代码:

class TextField(DisplayObject):
    def __init__(self):
        super(TextField, self).__init__()

        self.text = ""
        self.font = "Arial"
        self.size = 15
        self.textColor = "#000000"
        self.italic = False
        self.weight = TextFormatWeight.NORMAL

    def _getOriginalWidth(self):
        font = self.__getFont()
        fontMetrics = QtGui.QFontMetrics(font)

        return fontMetrics.width(str(self.text))

    def _getOriginalHeight(self):
        font = self.__getFont()
        fontMetrics = QtGui.QFontMetrics(font)

        return fontMetrics.height()

    def __getFont(self):
        weight = self.weight

        if self.weight == TextFormatWeight.NORMAL:
            weight = QtGui.QFont.Normal
        elif self.weight == TextFormatWeight.BOLD:
            weight = QtGui.QFont.Bold
        elif self.weight == TextFormatWeight.BOLDER:
            weight = QtGui.QFont.Black
        elif self.weight == TextFormatWeight.LIGHTER:
            weight = QtGui.QFont.Light

        font = QtGui.QFont()
        font.setFamily(self.font)
        font.setPixelSize(self.size)
        font.setWeight(weight)
        font.setItalic(self.italic)

        return font

    def _loopDraw(self, c):
        font = self.__getFont()
        flags = QtCore.Qt.AlignCenter
        width = self.width
        height = self.height

        pen = QtGui.QPen()
        pen.setColor(getColor(self.textColor))

        c.setFont(font)
        c.setPen(pen)
        c.drawText(0, 0, width, height, flags, str(self.text))

在这个类中,我们定义了一些和文本显示有关的属性,以下是这些属性的介绍:

  • text 显示的文本,是一个str对象
  • font 文本字体,也是一个str对象,如:“微软雅黑”
  • textColor 文本颜色,str类型,如:“red”
  • size 文本尺寸,int类型,默认单位是px
  • italic 文本是否是斜体
  • weight 文本粗细

由于这个类是继承自DisplayObject的,所以,除了上述的属性可以使用,还可以使用DisplayObject中的一切非私有属性,如xyrotation等。

现在开始代码分析。首先来看绘画部分_loopDraw方法。首先是通过__getFont获取一个字体,这个得到的字体是一个QFont对象,它包含了我们设置的字体,文本尺寸,文本粗细等一切和文本字体样式有关的属性。大家可以通过浏览__getFont的代码来了解这一点。
大家可能不太明白接下来我们定义的三个变量(flagwidthheight)的含义,这个其实是和绘制文本的方式有关。Qt绘制文本的方式是,首先给一个绘制文本的范围,然后给出绘制的文本相对于这个矩形的对齐方式,也就是flag变量(在Qt中,通过|来连接左右、上下的对齐方式,如flag = QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom就代表左下位置,而代码中的QtCore.Qt.AlignCenter表示上下都居中对齐)。
了解了绘画的原理,我们就不难理解QPainterdrawText方法了。前四个参数分别是用于确定绘制文本的范围的横纵坐标位置和宽高,第5个是对齐方式,第6个是显示的文本内容。
还有个QPen对象没有介绍。在Qt中,绘制工具分pen和brush,pen负责描边,而brush负责填充。而文本显示属于描边,所以通过设置pen来控制文本对象的颜色等样式。QPen对象就是用来实现pen的。
_getOriginalWidth_getOriginalHeight在上篇文章中也提到过,用于测定对象尺寸。Qt提供了QFontMetrics类来完成测定某一字体下,文本的宽高。值得注意的是,在宽高测定中,高度的测定和文本内容是没有关系的,只和字体有关。具体的使用方法见代码。

还有TextFormatWeight这个类,它是个静态类,用于装一些关于字体粗细的常量:

class TextFormatWeight(Object):
    NORMAL = "normal"
    BOLD = "bold"
    BOLDER = "bolder"
    LIGHTER = "lighter"

    def __init__(self):
        raise Exception("TextFormatWeight cannot be instantiated.")

Hello World小程序

有了上面的封装,就可以来完成Hello World小程序了:

from pylash import init, addChild, TextField

def main():
    txt = TextField()
    # set the content of the text field
    txt.text = "Hello World"
    # set color of text
    txt.textColor = "red"
    # set position
    txt.x = 50
    txt.y = 100
    # set size
    txt.size = 50
    # add text field into display list
    addChild(txt)

# parameters: refreshing speed, window title, window width, window height, callback
init(30, "Hello World", 800, 600, main)

效果图:

Python游戏引擎开发(四):TextField文本类_第1张图片

本次封装的代码:

class TextField(DisplayObject):
    def __init__(self):
        super(TextField, self).__init__()

        self.text = ""
        self.font = "Arial"
        self.size = 15
        self.textColor = "#000000"
        self.italic = False
        self.weight = TextFormatWeight.NORMAL

    def _getOriginalWidth(self):
        font = self.__getFont()
        fontMetrics = QtGui.QFontMetrics(font)

        return fontMetrics.width(str(self.text))

    def _getOriginalHeight(self):
        font = self.__getFont()
        fontMetrics = QtGui.QFontMetrics(font)

        return fontMetrics.height()

    def __getFont(self):
        weight = self.weight

        if self.weight == TextFormatWeight.NORMAL:
            weight = QtGui.QFont.Normal
        elif self.weight == TextFormatWeight.BOLD:
            weight = QtGui.QFont.Bold
        elif self.weight == TextFormatWeight.BOLDER:
            weight = QtGui.QFont.Black
        elif self.weight == TextFormatWeight.LIGHTER:
            weight = QtGui.QFont.Light

        font = QtGui.QFont()
        font.setFamily(self.font)
        font.setPixelSize(self.size)
        font.setWeight(weight)
        font.setItalic(self.italic)

        return font

    def _loopDraw(self, c):
        font = self.__getFont()
        flags = QtCore.Qt.AlignCenter
        width = self.width
        height = self.height

        pen = QtGui.QPen()
        pen.setColor(getColor(self.textColor))

        c.setFont(font)
        c.setPen(pen)
        c.drawText(0, 0, width, height, flags, str(self.text))

class TextFormatWeight(Object):
    NORMAL = "normal"
    BOLD = "bold"
    BOLDER = "bolder"
    LIGHTER = "lighter"

    def __init__(self):
        raise Exception("TextFormatWeight cannot be instantiated.")

预告:下一篇我们实现Sprite层次化效果及鼠标事件。

欢迎大家继续关注我的博客

转载请注明出处:Yorhom’s Game Box

http://blog.csdn.net/yorhomwang

你可能感兴趣的:(python,qt,textfield,游戏引擎)