четверг, 22 июля 2010 г.
среда, 7 июля 2010 г.
Пример использования QTextLayout в программе на PyQT
Пишу я программу для заполнения платёжных поручений, а то под Linux сушествующие пару прожек распрастраняемых банками не работают, а для некоторых дел заводить Windows и 1С как-то хлопотно и затратно очень.А я парень экономный:)
Результат должен быть ещё вчера, поэтому для ускорения написания был выбран Python.Прога должна хорошо смотреться в Windows и Gnome/KDE.Поэтому я выбрал PyQT, хотя мог бы и PyGTK заюзать.
Всё было хорошо, программа рендерила поручение на ура, но с назначением платежа у рендера траблы получалась.Ну не мог он при помощи QPainter.drawText() выводить строку так, что-бы если всё не умещалось в одну строку, рисовать две или три автоматически разбивая длинную строку на короткие.
Нужен был иной подход для рисования на шаблоне поручения этой строки.Облазил я документацию по QT и нашел выход в лице QTextLayout.Но сразу обломился - ведь нет примеров на PyQt как это добро юзать.А код примера то на C++...
В общем пришлось его переписать под Python, заодно и переделать немного из-за некоторых вещей, которые характерны для Python.
Результат моих мучений на скрине:
Встречайте готовый пример:
Результат должен быть ещё вчера, поэтому для ускорения написания был выбран Python.Прога должна хорошо смотреться в Windows и Gnome/KDE.Поэтому я выбрал PyQT, хотя мог бы и PyGTK заюзать.
Всё было хорошо, программа рендерила поручение на ура, но с назначением платежа у рендера траблы получалась.Ну не мог он при помощи QPainter.drawText() выводить строку так, что-бы если всё не умещалось в одну строку, рисовать две или три автоматически разбивая длинную строку на короткие.
Нужен был иной подход для рисования на шаблоне поручения этой строки.Облазил я документацию по QT и нашел выход в лице QTextLayout.Но сразу обломился - ведь нет примеров на PyQt как это добро юзать.А код примера то на C++...
В общем пришлось его переписать под Python, заодно и переделать немного из-за некоторых вещей, которые характерны для Python.
Результат моих мучений на скрине:
Встречайте готовый пример:
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
###########################################################################
## Copyright (C) 2010 RadiantPeak.
## This file based of Plain Text Layout examble.
## Ported from C++ to Python by RadiantPeak.
## Contain small python-specific modifications.
## If you use PyQt4 be patient, this framework have GPL or Comerial
## licence only.
## Contact: http://radiantpeak.blogspot.com
##
## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
## All rights reserved.
## Contact: Nokia Corporation (qt-info@nokia.com)
##
## This file is part of the documentation of the Qt Toolkit.
##
## $QT_BEGIN_LICENSE:LGPL$
## Commercial Usage
## Licensees holding valid Qt Commercial licenses may use this file in
## accordance with the Qt Commercial License Agreement provided with the
## Software or, alternatively, in accordance with the terms contained in
## a written agreement between you and Nokia.
##
## GNU Lesser General Public License Usage
## Alternatively, this file may be used under the terms of the GNU Lesser
## General Public License version 2.1 as published by the Free Software
## Foundation and appearing in the file LICENSE.LGPL included in the
## packaging of this file. Please review the following information to
## ensure the GNU Lesser General Public License version 2.1 requirements
## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
##
## In addition, as a special exception, Nokia gives you certain additional
## rights. These rights are described in the Nokia Qt LGPL Exception
## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
##
## GNU General Public License Usage
## Alternatively, this file may be used under the terms of the GNU
## General Public License version 3.0 as published by the Free Software
## Foundation and appearing in the file LICENSE.GPL included in the
## packaging of this file. Please review the following information to
## ensure the GNU General Public License version 3.0 requirements will be
## met: http://www.gnu.org/copyleft/gpl.html.
##
## If you have questions regarding the use of this file, please contact
## Nokia at qt-info@nokia.com.
## $QT_END_LICENSE$
##
###########################################################################
import sys
#Import some Qt classes from Qt library
pyQt = "PySide"
print sys.argv
if pyQt == "PyQt4":
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import *
from PyQt4.QtGui import *
else:
from PySide import QtGui, QtCore
from PySide.QtCore import *
from PySide.QtGui import *
#small workaround for PySide.
for index, arg in enumerate(sys.argv):
if type(arg) != str:
sys.argv[index] = str(arg)
class Label(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
#Create new font with font face 'Sans' and font size 8
self.setWindowTitle("Plain Text Layout")
self.font = QFont('Sans', 8)
text = str()
textlist =["Support for text rendering and layout in Qt 4 has been redesigned ",
"around a system that allows textual content to be represented in a ",
"more flexible way than was possible with Qt 3. Qt 4 also provides a ",
"more convenient programming interface for editing documents. These ",
"improvements are made available through a reimplementation of the ",
"existing text rendering engine, and the introduction of several new ",
"classes. See the relevant module overview for a detailed discussion ",
"of this framework. The following sections provide a brief overview ",
"of the main concepts behind Scribe."]
for line in textlist:
text = "{0}{1}".format(text, line)
#In python 2.6 QString takes a Unicode or ASCII string.
#If string contain non-ASCII symbols, use Unicode string.
#unicode string with utf-8 encoded source file and russian symbols raise a error.
#In this way use text.decode("utf-8")
self.text = QString(unicode(text.decode("utf-8")))
#Create new QTextLayout with our text and font
self.textLayout = QTextLayout(self.text, self.font)
def makeLayout(self):
"""This method create a layout with shape left edge"""
#define margin
self.margin = 10
self.radius = min(self.width()/2.0, self.height()/2.0) - self.margin
#Give a some font metrics
fm = QFontMetrics(self.font)
lineHeight = fm.height()
#default y position
y = 0
#Layout creation start
self.textLayout.beginLayout()
while (1):
# create a new line
self.line = self.textLayout.createLine()
#if self.line not valid, break the cycle
if (self.line.isValid()) != True:
break
#calculate the new position and width for our line
x1 = max(0.0, pow(pow(self.radius,2)-pow(self.radius-y,2), 0.5));
x2 = max(0.0, pow(pow(self.radius,2)-pow(self.radius-(y+lineHeight),2), 0.5))
x = max(x1, x2) + self.margin;
lineWidth = (self.width() - self.margin) - x
#Set new position and width fo created line
self.line.setLineWidth(lineWidth);
self.line.setPosition(QPointF(x, self.margin+y))
y += self.line.height()
self.textLayout.endLayout()
def paintEvent(self, event):
self.painter = QPainter()
self.painter.begin(self)
#Set render hint for Antialiasing
self.painter.setRenderHint(QPainter.Antialiasing)
#Fill wite rectangle as backround
self.painter.fillRect(QRect(0, 0, self.size().width(), self.size().height()), Qt.white)
#Create layout
self.makeLayout()
#Set pen and brush to black color
self.painter.setBrush(Qt.black)
self.painter.setPen(Qt.black)
#Draw layout to QPainter
self.textLayout.draw(self.painter,QPointF(0.0, 0.0))
#Set new brush color
self.painter.setBrush(QBrush(QColor("#a6ce39")))
#Draw the half of lime Ellipse
self.painter.drawEllipse(QRectF(-self.radius, self.margin, 2*self.radius, 2*self.radius))
self.painter.end()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = Label()
window.resize(337, 343)
window.show()
sys.exit(app.exec_())
Подписаться на:
Комментарии (Atom)
