RadiantPeak Home
Блог о жизни, Свободном ПО, языках программирования и других моих интересах.
четверг, 22 июля 2010 г.
среда, 7 июля 2010 г.
Пример использования QTextLayout в программе на PyQT
Результат должен быть ещё вчера, поэтому для ускорения написания был выбран 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_())
среда, 16 июня 2010 г.
Подсветка кода для вашего сайта
На днях надо было запостить листинг простенького скрипта, так пришлось
думать как подсветку ему прикрутить, у blogspot эта функция почему-то
не реализована.Решил поделится рецептом, вдруг ещё кому-то пригодиться.
Для начала нам нужно зайти на
http://github.com/ioquatix/jquery-syntax/downloads
,и скачать оттуда последнюю версию jQuery.Syntax, затем пройти на
http://jquery.com/ и там скачать сам jQuery фреймворк.
В результате после извлечения из архива jQuery.Syntax мы получим
следующее:
Каталог с произвольным именем вида: "ioquatix-jquery-syntax-7b0010b".
И файл "jquery-1.4.2.min.js", где цифры в названии обозначают версию и
могут отличаться от той, что у меня.
Ну, вроде всё собрал, теперь нужно всё это закинуть в новый
каталог, например в "jscripts".
А сейчас мы должны куда-то закинуть это добро, например на ваш хостинг,
или на любой сервис для хранения файлов с возможностью публичного
доступа к ним по HTTP.
Мой любимый сервис - https://www.dropbox.com/. Качаете для сервиса
клиент, проходите регистрацию, и залогинившись в клиенте, кидаете в
каталог "Public" приготовленный ранее каталог "jscripts".
Теперь нам надо узнать public link для доступа к каталогу "jscripts".
Заходим в каталог "jscripts", и выбираем пункт меню "Copy Public Link".
Получаем что-то такое:
http://dl.dropbox.com/u/циферки_какие-то/jquery-1.4.2.min.js
Затем от полученного адреса откусываем имя нашего файла, и получаем
ссылку на каталог "jscripts". Приблизительно такую:
http://dl.dropbox.com/u/циферки_какие-то/
А теперь заходим в шаблон нашего блога(Для blogspot надо зайти в
"Дизайн"->"Изменить HTML") и ищем в тексте шаблона тег <head>.
Там прописываем jQuery и jQuery.Syntax:
<!--Тут будет наш код.--> <!--Подключаем jQuery--> <script src='http://dl.dropbox.com/u/циферки_какие-то/jscripts/jquery-1.4.2.min.js' type='text/javascript' charset='utf-8' /> <!--Подключаем jQuery.Syntax--> <script src='http://dl.dropbox.com/u/циферки_какие-то/jscripts/jquery_syntax/jquery.syntax.min.js' type='text/javascript' charset='utf-8' /> <!--Подключаем скрипт, который после загрузки DOM модели документа начинает выполняться автоматически--> <script charset='utf-8' type='text/javascript'> // This function is executed when the page has finished loading. // Эта функция запускается, когда загрузка страницы завершена. jQuery(function($) { // This function does all the setup and then highlights (by default) pre and code tags which are annotated correctly. //Эта функция устанавливает обработчик для подсветки тегов pre и code , если они правильно объявены. $.syntax({root:"http://dl.dropbox.com/u/7624165/jscripts/jquery_syntax/"}); }); </script> <!--Конец нашего кода-->
Выглядит это так:
<head>
Наш код сразу за head.
А это всё, что тут было.
</head>
Теперь для тех, у кого страничка или блог не на blogspot'е. Вам надо
просто отредактировать текст шаблона вашего сайта. Как это сделать -
можно узнать из справки вашего сервиса, или руководстве к вашей
CMS.
Если ваш каталог "scripts" вы разместили на другом сервисе, узнайте как
получить доступ к файлам каталога по HTTP. И соответственно измените
путь в вашем коде.
Замените "http://dl.dropbox.com/u/7624165/jscripts/jquery_syntax/" на
"http://адрес_хостинга_или_сервиса_хранения/путь_к_нашим_файлам/".
А теперь в вашей статье или заметке обрамите код на каком-то языке
тегом code или pre.
Допустим у нас есть код на языке C++:
#include
int main()
{
std::cout << "Hello World!" << std::endl;
}
Помещаем его внутрь тега pre:
<pre class="syntax brush-clang">
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
}
</pre>
И получаем в результате такой вот блок с подсвеченным исходником.
#include <iostream> int main() { std::cout << "Hello World!" << std::endl; }
Как включить подсветку для блоков с другими языками описано на
http://www.oriontransfer.co.nz/software/jquery-syntax/examples/index
Удачи в ваших экспериментах. Желаю всем счастья и результативной работы.