четверг, 22 июля 2010 г.

Java script in body test...

среда, 7 июля 2010 г.

Пример использования QTextLayout в программе на PyQT

Пишу я программу для заполнения платёжных поручений, а то под Linux сушествующие пару прожек распрастраняемых банками не работают, а для некоторых дел заводить Windows и 1С как-то хлопотно и затратно очень.А я парень экономный:)

Результат должен быть ещё вчера, поэтому для ускорения написания был выбран 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


Удачи в ваших экспериментах. Желаю всем счастья и результативной работы.