18 марта 2014 г.

Релиз Python 3.4.0

Вчера 17.03.2014 вышел в свет новый мажорный релиз интерпритатора Python 3.4 как обешшал
Великодушный пожизненный диктатор — Гвидо ван Россум эта версия обешшает скорость и стабильность 2.7 ветки.
Также сегодня ожидается релиз JDK 8.0.

25 сентября 2013 г.

PyCharm Community Edition

Для языка программирования Python есть очень хорошая среда, PyCharm. Это самая лучшая IDE для данного языка. Так вот сегодня вышла новая бесплатная редакция среды Community Edition.
она имеет урезанный функционал но все равно для большинства Python программистов этого будет вполне достаточно.
Здесь можно посмотреть разницу между бесплатной и платной версией.

16 сентября 2013 г.

Работаем с Ajax в Django

Для работы с Ajax в Django имеется очень легкий и простой в использовании библиотека django-dajaxice. С его помощью можно буквально за несколько минут заставить работать Ajax запросы в нашем django приложении.
Итак создаем проект на django. Открываем консоль и выполняем команду

>django-admin.py startproject mysite


Создаем приложение.

>django-admin.py startapp myapp


Убеждаемся что параметры проекта в файле settings.py имеют вид

# Django settings for mysite project.

.....

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'dajaxice.finders.DajaxiceFinder',
#    'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

....

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
    'django.template.loaders.eggs.Loader',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.request',
    'django.contrib.messages.context_processors.messages'
)

.....

import os
TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), '..', 'templates').replace('\\','/'),)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'dajaxice',
    'myapp',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)

.....
Редактируем urls.py
from django.conf.urls import patterns, include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from dajaxice.core import dajaxice_autodiscover, dajaxice_config

dajaxice_autodiscover()

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', 'myapp.views.index'),
    url(dajaxice_config.dajaxice_url, include('dajaxice.urls')),
    # Examples:
    # url(r'^$', 'mysite.views.home', name='home'),
    # url(r'^mysite/', include('mysite.foo.urls')),
    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    # Uncomment the next line to enable the admin:
    # url(r'^admin/', include(admin.site.urls)),
)
urlpatterns += staticfiles_urlpatterns()
Пишем шаблон index.html
<!DOCTYPE html>
<html>
<head>
    <title></title>

    {% load dajaxice_templatetags %}
    {% dajaxice_js_import %}

    <script>
        function square(sourse, number){
            
            function callback_square(data){
                alert(data.number);
            }
            
            Dajaxice.myapp.views.square(callback_square, {number:number })                 

        }
    </script>
    
</head>
<body>
<input type="text" onclick="square(this, this.value)">
</body>
</html>
И обработчик запросов myapp\views.py
import json
from dajaxice.decorators import dajaxice_register
from django.shortcuts import render_to_response

def index(request):
    return render_to_response('index.html')


@dajaxice_register
def square(request, number):
    print int(number)
    number=int(number)*int(number)
    return json.dumps({'number':number})

Запускаем сервер разработки

>manage.py runserver

и открываем в браузере адрес http://127.0.0.1:8000, проверяем вводим число в поле и шелкаем по нему.

Файлы из примера,  сайт проекта.

4 июля 2012 г.

Пример использования QSqlRelationalTableModel в PySide

QSqlRelationalTableModel используется PySide для работы с таблицами которые имеют поле foreign key. Для работы с foreign key достаточно использовать метод setRelation с параметрами состоящими из номера поля, таблицы от куда подставляют значения, поле идентификатора и поле  значений идентификатора. Также при использовании QSqlRelationalTableModel есть возможность использовать QComboBox в связанных полях в QTableView. Для этого нужно использовать метод setItemDelegate класса QTableView. Пример.
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 03 16:48:15 2012

@author: Amin
"""
from PySide import QtGui, QtSql, QtCore
import sys


class Form(QtGui.QWidget):
    def __init__(self, parent=None):
        # Создаем кнопки, поля, гриды для работы с данными
        super(Form, self).__init__(parent)
        self.label = QtGui.QLabel(self)
        self.lineEdit = QtGui.QLineEdit(self)
        self.label_2 = QtGui.QLabel(self)
        self.comboBox = QtGui.QComboBox(self)
        self.pushButton = QtGui.QPushButton(self)
        self.pushButton_2 = QtGui.QPushButton(self)
        self.pushButton_3 = QtGui.QPushButton(self)
        self.pushButton_4 = QtGui.QPushButton(self)
        self.pushButton_5 = QtGui.QPushButton(self)
        self.pushButton_6 = QtGui.QPushButton(self)
        self.label_3 = QtGui.QLabel(self)
        self.label_4 = QtGui.QLabel(self)
        self.tableView = QtGui.QTableView(self)
        self.tableView_2 = QtGui.QTableView(self)    
        self.label.setText(u'Ученик')
        self.label_2.setText(u'Класс')
        self.label_3.setText(u'Список учеников')
        self.label_4.setText(u'Список классов')
        self.pushButton.setText(u'Сохранить ученика')
        self.pushButton_2.setText(u'Новый ученик')
        self.pushButton_3.setText(u'Предижущая')
        self.pushButton_4.setText(u'Следующая')
        self.pushButton_5.setText(u'Добавить класс')
        self.pushButton_6.setText(u'Сохранить класс')
        #Размещаем элемениы управления по сетке
        self.gridLayout = QtGui.QGridLayout(self)
        self.gridLayout.setContentsMargins(5, 5, 5, 5)
        self.gridLayout.addWidget(self.tableView_2, 2, 5, 1, 7)
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.label_2, 0, 2, 1, 1)
        self.gridLayout.addWidget(self.comboBox, 0, 3, 1, 1)
        self.gridLayout.addWidget(self.pushButton, 0, 5, 1, 1)
        self.gridLayout.addWidget(self.pushButton_2, 0, 4, 1, 1)
        self.gridLayout.addWidget(self.pushButton_3, 0, 6, 1, 1)
        self.gridLayout.addWidget(self.pushButton_4, 0, 7, 1, 1)
        self.gridLayout.addWidget(self.pushButton_5, 3, 5, 1, 1)
        self.gridLayout.addWidget(self.pushButton_6, 3, 6, 1, 1)
        self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
        self.gridLayout.addWidget(self.label_4, 1, 5, 1, 1)
        self.gridLayout.addWidget(self.tableView, 2, 0, 1, 5)
        
        self.mapdata()
    
    def mapdata(self):
        #Простая таблица со списком классов
        self.formmodel = QtSql.QSqlTableModel()
        self.formmodel.setTable('forms')
        self.tableView_2.setModel(self.formmodel)
        self.formmodel.select()
        
        #Модель с foreign полем
        self.studmodel = QtSql.QSqlRelationalTableModel()
        self.studmodel.setTable('studients')
        self.studmodel.setRelation(2, QtSql.QSqlRelation('forms', 'id', 'name'))
        
        #Таблица с foreign полем
        self.tableView.setModel(self.studmodel)
        self.tableView.setItemDelegate(QtSql.QSqlRelationalDelegate(self.tableView))
        self.studmodel.select()
        
        self.mapper = QtGui.QDataWidgetMapper(self)
        self.mapper.setModel(self.studmodel)
        
        #ComboBox с foreign полем
        self.mapper.setItemDelegate(QtSql.QSqlRelationalDelegate(self))
        self.mapper.addMapping(self.lineEdit, 1)
        self.rellmap = self.studmodel.relationModel(2)
        self.comboBox.setModel(self.rellmap)
        self.comboBox.setModelColumn(self.rellmap.fieldIndex('name'))
        self.mapper.addMapping(self.comboBox, 2)
        
        self.mapper.toFirst()         

        self.connect(self.pushButton, QtCore.SIGNAL('clicked()'), self.studmodel.submit)                          
        self.connect(self.pushButton_2, QtCore.SIGNAL('clicked()'), self.new_std)
        self.connect(self.pushButton_3, QtCore.SIGNAL('clicked()'), self.mapper.toPrevious)
        self.connect(self.pushButton_4, QtCore.SIGNAL('clicked()'), self.mapper.toNext)
        self.connect(self.pushButton_5, QtCore.SIGNAL('clicked()'), self.new_form)
        self.connect(self.pushButton_6, QtCore.SIGNAL('clicked()'), self.formmodel.submit)
        
    def new_std(self):
        row = self.studmodel.rowCount()
        self.mapper.submit()
        self.studmodel.insertRow(row)
        self.mapper.setCurrentIndex(row)
        self.lineEdit.setFocus()

    def new_form(self):
        row = self.formmodel.rowCount()
        self.formmodel.insertRow(row)
        

#приложение
main=QtGui.QApplication(sys.argv)
#подключение база
dbase = QtSql.QSqlDatabase.addDatabase('QSQLITE')
#файл базы
dbase.setDatabaseName('my_db.sqlite')
dbase.open()

query=QtSql.QSqlQuery()
#Создаем базу
query.exec_('''CREATE TABLE forms
                (id integer PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                name VARCHAR(9));''')
query.exec_('''CREATE TABLE studients
                (id integer PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                name VARCHAR(255),
                form_id integer,
                FOREIGN KEY (form_id ) REFERENCES forms);''')

        
my_win = Form()
my_win.show()
sys.exit(main.exec_())        
Вот результат работы.

28 июня 2012 г.

Пример использования QDataWidgetMapper в PySide

В одном из постов данного блога был пост на тему использования Базы Данных из PySide. Теперь постараемся расширить тот скрипт и приделать к полям таблицы редактируемые элементы управления.
Для этого нам понадобится класс QDataWidgetMapper. Этот класс реализует связь между моделью таблицы и элементами управления.
Сначала нужно будет создать объект QDataWidgetMapper. Связать его с моделью использую функцию setModel() и связать поля модели с элементами управления на форме. Пример.
# coding=utf-8
import sys

from PySide import QtGui, QtSql, QtCore

#приложение
main=QtGui.QApplication(sys.argv)
#подключение база
dbase = QtSql.QSqlDatabase.addDatabase('QSQLITE')
#файл базы
dbase.setDatabaseName('my_db.sqlite') 
dbase.open()
query=QtSql.QSqlQuery()
#Создаем базу
query.exec_('''CREATE TABLE forms 
                (id integer PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, 
                name VARCHAR(9));''')
query.exec_('''CREATE TABLE studients 
                (id integer PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, 
                name VARCHAR(255), 
                form_id integer,
                FOREIGN KEY (form_id ) REFERENCES forms);''')



class Form(QtGui.QWidget):
    def __init__(self, parent=None):
        # Создаем кнопки, поля, грди для работы с данными
        super(Form, self).__init__(parent)     
        self.gridLayout = QtGui.QGridLayout(self)
        self.gridLayout.setContentsMargins(5, 5, 5, 5)
        self.label = QtGui.QLabel('ID')
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.lineEdit = QtGui.QLineEdit()
        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 2)
        self.label_2 = QtGui.QLabel('Name')
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.lineEdit_2 = QtGui.QLineEdit()
        self.gridLayout.addWidget(self.lineEdit_2, 1, 1, 1, 2)
        
        self.button_prev = QtGui.QPushButton('Prev')
        self.gridLayout.addWidget(self.button_prev, 2, 1, 1, 1)
        self.button_next = QtGui.QPushButton('Next')
        self.setLayout(self.gridLayout)
        self.gridLayout.addWidget(self.button_next, 2, 2, 1, 1) 
        self.view = QtGui.QTableView()
        self.gridLayout.addWidget(self.view, 3, 1,1,2)
        self.bind_data()
        
    def bind_data(self):
        #типа DBGird
        
        #типа Tabel
        self.model = QtSql.QSqlTableModel()
        self.model.setTable('forms')
        
        self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
        #Связываем грид с таблицой
        self.view.setModel(self.model)
        
        self.data_mapper = QtGui.QDataWidgetMapper()
        # связиваем мапер с таблицой
        self.data_mapper.setModel(self.model)
        #Связываем поля
        self.data_mapper.addMapping(self.lineEdit, 0)
        self.data_mapper.addMapping(self.lineEdit_2, 1)
        self.model.select()
        self.data_mapper.toFirst()
        
        # переход между записями по книпкам
        self.connect(self.button_next, QtCore.SIGNAL('clicked()'), self.data_mapper.toNext)
        self.connect(self.button_prev, QtCore.SIGNAL('clicked()'), self.data_mapper.toPrevious)
        
my_win = Form()
my_win.show()
sys.exit(main.exec_())
Вот то что должно получится в итоге.


Редактируем тему Eclipse Juno для XP

После закачки, распаковки, и запуска нового Eclipse Juno увидел что новая тема программы не совсем соответствует стилю Windows XP.
Пошлость поковыряется в свойствах стиля. И так мы имеем в папке plugins\org.eclipse.platform_4.2...\css\ файлs стилей Eclipse, открываем один из файл e4_default_winxp_blu.css и приводим его в следующий вид.
@import url("e4_basestyle.css");

.MTrimmedWindow { 
  background-color: #F0ECE0; 
}

.MPartStack {
 font-size: 9;
 swt-simple: true;
 swt-mru-visible: false;
}

.MTrimBar {
    background-color: #F0ECE0; 
}


.MTrimBar#org-eclipse-ui-main-toolbar  {
    background-color: #EBE6DC #F0ECE0;
}

.MToolControl.TrimStack {
 frame-image:  url(./winXPBluTSFrame.png);
 handle-image:  url(./winXPBluHandle.png);
}

.MPartStack.active {
 swt-unselected-tabs-color: #EBE6DC #F0ECE0 #FFFFFF 100% 100%;
    swt-outer-keyline-color: #B8C7E5;
}

#PerspectiveSwitcher  {
 background-color: #F5F3ED #F0ECE0 100%;
 eclipse-perspective-keyline-color: #7F91B5 #7F91B5;
}

#org-eclipse-ui-editorss {
   swt-tab-renderer: url('bundleclass://org.eclipse.e4.ui.workbench.renderers.swt/org.eclipse.e4.ui.workbench.renderers.swt.CTabRendering');
   swt-unselected-tabs-color: #F0F0F0 #F0F0F0 #F0F0F0 100% 100%;
   swt-outer-keyline-color: #B4B4B4;
   swt-inner-keyline-color: #F0F0F0;
   swt-tab-outline: #F0F0F0;
   color: #F0F0F0;
   swt-tab-height: 8px;
   padding: 0px 5px 7px;
}

CTabFolder.MArea .MPartStack, CTabFolder.MArea .MPartStack.active {
   swt-shadow-visible: false;
}

CTabFolder Canvas {
  background-color: #F8F8F8;
}
Далее выбираем Window-> Preferences->General->Appearance выставляем Theme равным Windows XP Blue. Вот результат.
UPD: Есть E4 Toos которым можно редактировать CSS стиль среды непосредственно на странице настроек(работает не очень стабильно). http://habrahabr.ru/post/147417/

27 июня 2012 г.

Eclipse 4.2 Juno

Как и любой другой ленивый программист люблю пользоваться умными и удобными инструментами. Сегодня состоялся очередной ежегодный релиз Eclipse. Но пока нет доступа для прямого скачивание дистрибутива из зеркал Eclipse Foundatin. Скачивание пока доступно
Так называемым друзьям Eclipse. Ну а для всех остальных торренты.