html текст
All interests
  • All interests
  • Design
  • Food
  • Gadgets
  • Humor
  • News
  • Photo
  • Travel
  • Video
Click to see the next recommended page
Like it
Don't like
Add to Favorites

Разработка клиентской части приложения информационной системы торговой организации с помощью Qt

В рамках учебного курса «Средства визуального программирования приложений» (ИПКиПК) мы познакомились с Qt - кросс-платформенным инструментарием разработки ПО на языке программирования C++. Этап написания курсовой работы состоял из двух частей. В первой части, на занятиях по управлению базами данных мы разработали структуру базы данных MySQL и различные запросы, согласно своему варианту курсовой работы. Во второй части, мы разработали клиентскую часть приложения на Qt с использованием среды разработки Qt Creator и средой разработки графического интерфейса Qt Designer.

Теоретическая основа разработки автоматизированной информационной системы

В теоретической части курсовой работы рассмотрены основы разработки автоматизированной информационной системы: процесс создания, проектирования и использования базы данных MYSQL, реализация различных классов при разработке приложений с  использованием библиотеки Qt.

Проектирование и разработка клиентского приложения информационной системы торговой организации

В практической части  курсовой работы реализована структура базы данных торгового предприятия и описан процесс создания клиентского приложения с использованием программы Qt.

Проектирование базы данных торговой организации начиналось с создания всех нужных таблиц в базе, всех полей входящих в каждую таблицу, взаимодействия таблиц между собой с помощью специальных отношений (один ко многим, многие ко многим) и создание в соответствии с этими параметрами первичных и вторичных ключей.

Структура базы данных информационной системы торговой организации (файл ipk2012.sql):

Таблицы MySQL в клиентском приложении Qt

I. Торговая точка (trade)
1. Номер точки (trade_id)
2. Тип торговой точки (универмаг, магазин, киоск) (trade_type)
3. Число торговых залов (trade_number)
4. Платежи за аренду (стоимость) (trade_rent)
5. Коммунальные услуги (стоимость) (trade_utilities)

II. Продавец (seller)
1. Номер (seller_id)
2. Фамилия (seller_family)
3. Имя (seller_name)
4. Оклад (seller_oklad)
5. Код торговой точки (trade_id)

III. Заявка (application)
1. Номер заявки (application_id)
2. Наименование товара (application_description)
3. Количество (application_sum)
4. Стоимость (application_cost)
5. Дата заявки (application_date)
5. Код товара (catalog_id)
6. Код поставщика (distributor_id)

IV. Поставщик (distributor)
1. Номер (distributor_id)
2. Категория (фирма, дилер) (distributor_category)
3. Адрес (distributor_adress)
4. Название (distributor_name)

V. Покупатель (buyer)
1. Номер покупателя (buyer_id)
2. Имя покупателя (buyer_name)
3. Фамилия покупателя (buyer_family)
4. Тип (частное или физическое лицо) (buyer_type)

VI. Продажи (sales)
1. Номер покупки (sales_id)
2. Дата покупки (sales_date)
3. Количество единиц (sales_sum)
4. Цена (sales_price)
5. Код товара (catalog_id)
6. Код продавца (seller_id)
7. Код покупателя (buyer_id)

VII. Справочник товаров (номенклатура, склад) (catalog)
1. Номер товара (catalog_id) - первичный
2. Название товара (catalog_name)
3. Количество (catalog_sum)
4. Цена (catalog_price)

VIII. Распределение (raspredelenie)
1. Код товара (catalog_id)
2. Код точки (trade_id)

Разработка клиентского приложения в Qt Creator

Главная страница Qt-проекта

В библиотеке Qt есть отдельный модуль, предоставляющий удобный функционал использования базы данных — QtSql.

К уровню драйверов относятся классы для получения данных на физическом уровне, такие, как:

  • QSqlDriver;
  • QsqlDriverCreator <T*>;
  • QSqlDriverCreatorBase;
  • QSqlDriverPlugin;
  • QSqlResult.

QSqlDriver является абстрактным базовым классом, предназначенный для доступа к специфичным БД. Класс не должен быть использован «прямо», взамен нужно воспользоваться QsqlDatabase. Для создания собственного драйвера SQL можно наследовать функции от QSqlDriver и реализовать необходимые виртуальные функции.

QSqlDriverCreator — шаблонный класс, предоставляющий фабрику SQL драйвера для специфичного типа драйвера. Шаблонный параметр должен быть подклассом QSqlDriver.

QSqlCreatorBase — базовый класс для фабрик SQL драйверов, чтобы возвращать экземпляр специфичного подкласса класса QSqlDriver.
QSqlDatabase несет ответственность за загрузку и управление плагинов драйверов баз данных. Когда база данных добавлена с помощью функции QSqlDatabase::addDatabase()), необходимый плагин драйвера загружается, используя QSqlDriverPlugin. QSqlDriverPlugin предоставляет собой абстрактный базовый класс для пользовательских QSqlDriver плагинов.

QSqlResult предоставляет абстрактный интерфейс для доступа к данным специфичных БД. В курсовом проекте мы используем  QSqlQuery вместо QSqlResult, поскольку QSqlQuery предоставляет обертку для БД-специфичных реализации QSqlResult.

В проекте файла ipk2012.pro записываются все основные подключения и название проекта. Для того чтобы, проект мог работать с базой банных и обрабатывать запросы на sql в первой строке  указывается код: sql: QT += core gui sql.

В файле mainwindow.h указывается подключение нужных библиотек, описание  выбранного класса, описание конструктора, описание записанных слотов (записываются автоматически при создании), описание соответствующих указателей и функций (листинг 1.1).

Листинг 1.1 – Подключение библиотек в QT

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>     окно Qmainwindow
#include <QTextCodec>      кодеки для использования русских симовлов
#include <QtSql/QSqlDatabase>  создание или подключение базы
#include <QtSql/QSqlRelationalTableModel> создание реляционной таблицы модели
#include <QApplication>   создание аппликации
#include <QDataWidgetMapper>  создание определённых виджетов
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow   описание класса и наследование
{
    Q_OBJECT
public:
    explicit MainWindow(QApplication *a, QWidget *parent = 0);   описание конструктора
    ~MainWindow();     описание деструктора          
private slots:      описание слотов
    void on_actionExit_triggered();
    void on_action_triggered();
    void on_action_2_triggered();
    void on_action_3_triggered();
    void on_action_4_triggered();
    void on_action_5_triggered();
    void on_action_6_triggered();
    void on_action_7_triggered();
    void on_action_8_triggered();
    void on_action_9_triggered();
    void on_action_10_triggered();
    void on_action_11_triggered();
    void on_action_12_triggered();
    void on_action_13_triggered();
    void on_action_14_triggered();
    void on_action_15_triggered();
private:
    Ui::MainWindow *ui;  указатель на класс
    QTextCodec *codec;   указатель на кодеки
    QSqlDatabase *db;   указатель на подключение или создание
    QAbstractTableModel *model; указатель на абстрактную модель таблицы
    bool createConnection();  функция создания подключения
    void createRelationalTables(); функция создания реляционной таблицы
    void initializeModel();  функция инициализации модели
};
#endif // MAINWINDOW_H

ПВ файле mainwindow.cpp записывается подключения нужных библиотек, файлов, а также весь процесс реализации данного класса mainwindow (листинг 3.2).

Листинг 1.2 – Реализация класса mainwindow

Реализация класса mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"                подключения файла данной формы
#include <QtSql/QSqlDatabase>           создания или подключение базы   
#include <QtSql/QSqlError>                ошибок подключения
#include <QtSql/QSqlQuery>                ошибок запросов
#include <QMessageBox>                     текстовых сообщений
#include <QtSql/QSqlTableModel>      создания реляционной таблицы
#include <QDataWidgetMapper>         создания определённых виджетов
#include <QFile>                                   создания для работы с файлами
#include <QSqlRelationalDelegate>     создания реляционного делегата типа sql
#include <QDate>                                  создания функции для работы с датами в Qt4
#include <QApplication>                       создания аппликации
#include <QPushButton.h>                    создания виджета типа QPushButton
#include <QPrinter>                               создания класса Qprinter
#include <QTextDocument>                  создания класса QTextDocument
#include <QPrintDialog>                       создания класса QPrintDialog
#include <QTextCodec>                        создания кодеков для отображения  текста  
#include "dialog.h"                                 подключение файлов формы диалог
#include "dialog2.h"

MainWindow::MainWindow(QApplication *a, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)        процесс реализации класса и конструктора с параметрами и выделения памяти
{
    ui->setupUi(this);                     указатель на setupUi
    QTextCodec *codec = QTextCodec::codecForName("CP1251");
    codec = QTextCodec::codecForName("CP1251"); установка кодировки сp1251 для отображения русских символов среде Qt
    QTextCodec::setCodecForTr(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForLocale(codec);
    ui->tw->horizontalHeader()->setResizeMode(QHeaderView::Stretch);    установка горизонтальной шапки таблицы
    ui->tw->setItemDelegate(new QSqlRelationalDelegate(ui->tw)); создание реляционного делегата типа sql и выделения для него памяти
    ui->tw->setWindowTitle("Информационная система торговой организации");
    QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL"); подключение к MYSQL
    db.setHostName("127.0.0.1"); Имя хоста
    db.setPort(3306); Порт
    db.setDatabaseName("ipk2012"); Название базы данных MYSQL
    db.setUserName("root"); Имя пользователя базы данных MYSQL
    db.setPassword("12345"); Пароль
    if (!db.open())
    {
        QMessageBox::critical(parent,QObject::tr("Database Error"),db.lastError().text());
    }     Процесс вывода ошибки при невозможности подключиться к базе данных
    QSqlTableModel *model=new QSqlTableModel;    создание реляционной модели и выделение для неё памяти
    model->setTable("trade");
    if (model->lastError().isValid() ) процедура вывода ошибки
    {
       QMessageBox::critical(parent,QObject::tr("Query Error"),model->lastError().text());
    }
    model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер точки"));
    model->setHeaderData(1, Qt::Horizontal, QObject::tr("Тип торговой точки"));
    model->setHeaderData(2, Qt::Horizontal, QObject::tr("Число торговых залов"));
    model->setHeaderData(3, Qt::Horizontal, QObject::tr("Платежи за аренду, руб."));
    model->setHeaderData(4, Qt::Horizontal, QObject::tr("Коммунальные услуги, руб."));   Описание шапки таблицы с помощью функции setHeaderData
    model->select();    Функция выборки
    ui->tw->setModel(model); Указатель на модель
    this->model = model;
    ui->tw->show();  Функция show-вывод на экран
    model->submitAll(); Функция submitall-представляет запись всех изменений
}
MainWindow::~MainWindow()  Деструктор класса
{
    delete ui;
}

Процедура выполнения готовых  всех классов выполняется в файле main.cpp (листинг 1.3).

Листинг 1.3 – Выполнение классов в файле main.cpp

#include <QtGui/QApplication>  подключение библиотеки QApplication
#include "mainwindow.h" подключение файла mainwindow.h
#include <QTextCodec>  подключение библиотеки QTextCodec
int main(int argc, char *argv[])   
{
    QApplication a(argc, argv); выполнение класса   QApplication a
    MainWindow w(&a);   выполнение класса     MainWindow w(&a)
    w.show();     вывод на экран класс    w.show();                              
    return a.exec();
}

Для вывода таблиц используется виджет Qtableview (модель таблицы для отображения таблиц базы данных и запросов).  Описывая слот и процедуру, применяется обработка события мыши типа щелчок. Все данные процедуры события автоматически записываются в файл mainwindow.сpp. Здесь указывается алгоритм вывода таблицы или определенного запроса (листинг 1.4).

Листинг 1.4 – Вывод таблиц с помощью функции QSqlTableModel

void MainWindow::on_actionExit_triggered()
{
    QMessageBox::information(0,"Info","exit pressed.");
}
void MainWindow::on_action_triggered()
{
    QSqlTableModel *model=new QSqlTableModel;
    model->setTable("trade");
    model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер точки"));
    model->setHeaderData(1, Qt::Horizontal, QObject::tr("Тип торговой точки"));
    model->setHeaderData(2, Qt::Horizontal, QObject::tr("Число торговых залов"));
    model->setHeaderData(3, Qt::Horizontal, QObject::tr("Платежи за аренду, руб."));
    model->setHeaderData(4, Qt::Horizontal, QObject::tr("Коммунальные услуги, руб."));
    model->select();
    ui->tw->setModel(model);
    delete this->model;
    this->model = model;
ui->tw->show();
}

Текст обработки события для добавления строки имеет такой код (листинг 1.5):

Листинг 1.5 – Добавление строки

void MainWindow::on_action_8_triggered()
    {
   model->insertRow(model->rowCount());
    }

При удалении строки необходимо ввести параметр currentIndex для того, чтобы происходил процесс удаления текущей строки (удаление строки):

Листинг 3.6 – Удаление строки

void MainWindow::on_action_9_triggered()
    {
            model->removeRow(ui->tw->currentIndex().row());
    }

Для выполнения однотабличных и многотабличных запросов в клиентском приложении использовался простой вывод таблицы в окне mainwindow по выбранным запросам и диалоговые окна с функцией выбора параметра.

Для реализации диалогового окна в визуальном файле dialog.ui указываются нужные виджеты: label (текст описания поля) и lineedit (поле для введения данных пользователем).

Реализация диалогового окна dialog в QT

Листинг 1.7 – Описание файла dialog.h

#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>  подключение библиотеки Qdialog
namespace Ui {
class Dialog;
}

class Dialog : public QDialog описание класса и наследование Qdialog
{
    Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);  конструктор типа dialog
    ~Dialog();    деструктор типа dialog
    QString search();QString search_2();QString search_3();QString search_4();  описание функций типа qstring  для записи текста из виджета типа lineedit
  private slots:
private:
    Ui::Dialog *ui;   указатель ui в форме dialog
};
#endif // DIALOG_H

 

В файле dialog.cpp подключается  заголовочный файл dialog.h и ui_dialog.h.  (листинг 3.8). Здесь происходит процесс реализации класса и конструктора dialog, выделение записи для конструктора  и реализация функции  QString search().

Реализация диалоговых окон в Qt Designer

Листинг 1.8 – Реализации класса,  конструктора dialog и функции QString search()

#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}
Dialog::~Dialog()
{
    delete ui;
}
QString Dialog::search()
{
    return ui->lineEdit->text();
}
QString Dialog::search_2()
{
    return ui->lineEdit_2->text();
}

В ходе разработки приложения были разработаны следующие типы запросов:

1. Поиск продавцов по критерию «Фамилия» и номеру торговой точки (листинг 1.9)

Листинг 1.9 – Тип запроса «Поиск продавцов по критерию «Фамилия» и номеру торговой точки»

void MainWindow::on_action_10_triggered()
{
    Dialog dialog;
    if (dialog.exec())
    {
    QString p=dialog.search();QString d=dialog.search_2();
    QSqlError sqlError;
    QSqlQueryModel *model = new QSqlQueryModel;
    if (d=="") {    model->setQuery("select seller_id, seller_family, seller_name, seller_oklad, trade_id from seller WHERE seller_family = \'"+p+"\'  ");
        model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер"));
        model->setHeaderData(1, Qt::Horizontal, QObject::tr("Фамилия продавца"));
        model->setHeaderData(2, Qt::Horizontal, QObject::tr("Имя продавца"));
        model->setHeaderData(3, Qt::Horizontal, QObject::tr("Оклад"));
        model->setHeaderData(4, Qt::Horizontal, QObject::tr("Номер торговой точки"));
    }
    if(d!="") {
    model->setQuery("select seller_id, seller_family, seller_name, seller_oklad, trade_id from seller WHERE seller_family = \'"+p+"\' and trade_id =\'"+d+"\' ");
    model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер"));
    model->setHeaderData(1, Qt::Horizontal, QObject::tr("Фамилия продавца"));
    model->setHeaderData(2, Qt::Horizontal, QObject::tr("Имя продавца"));
    model->setHeaderData(3, Qt::Horizontal, QObject::tr("Оклад"));
    model->setHeaderData(4, Qt::Horizontal, QObject::tr("Номер торговой точки"));
    }
    sqlError = model->lastError();
    if (sqlError.type()!=QSqlError::NoError)
    {
        QMessageBox::critical(this,"SQL Error", sqlError.text());
    }
//! [3]
    ui->tw->setModel(model);
    delete this->model;
    this->model = model;
    }
}

2. Общее количество товаров на складе (листинг 1.10)

Листинг 1.10 – Тип запроса «Количество товаров на складе»

void MainWindow::on_action_11_triggered()
    {
        QSqlQueryModel *model=new QSqlQueryModel;
        model->setQuery("SELECT catalog_id, catalog_name, catalog_sum FROM catalog");
        model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер товара"));
        model->setHeaderData(1, Qt::Horizontal, QObject::tr("Название товара"));
        model->setHeaderData(2, Qt::Horizontal, QObject::tr("Количество"));
        ui->tw->setModel(model);
        delete this->model;
        this->model = model;
        ui->tw->show();
    }

3. Количество оформленных покупателями товаров с сортировкой по полю дата (листинг 1.11)

Листинг 1.11 – Тип запроса «Оформленные заказы с сортировкой по дате»

void MainWindow::on_action_12_triggered()
    {
        QSqlQueryModel *model=new QSqlQueryModel;
        model->setQuery("SELECT catalog_id, sales_sum, sales_price, sales_date from sales ORDER BY sales_date DESC");
        model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер товара"));
        model->setHeaderData(1, Qt::Horizontal, QObject::tr("Количество товаров"));
        model->setHeaderData(2, Qt::Horizontal, QObject::tr("Стоимость товара"));
        model->setHeaderData(3, Qt::Horizontal, QObject::tr("Дата оформления заказа"));
        ui->tw->setModel(model);
        delete this->model;
        this->model = model;
        ui->tw->show();
    }

4. Оформленные товары с фамилией и именем покупателей с сортировкой по дате (многотабличный запрос) (листинг 1.12)

Листинг 1.12 – Тип запроса «Оформленные товары покупателей с сортировкой по дате»

void MainWindow::on_action_13_triggered() // многотабличный запрос
    {
        QSqlQueryModel *model=new QSqlQueryModel;
        model->setQuery("SELECT buyer.buyer_name, buyer.buyer_family, catalog.catalog_name, sales.sales_date from buyer, catalog, sales WHERE buyer.buyer_id = catalog.catalog_id AND catalog.catalog_id = sales.sales_id ORDER BY sales_date DESC");
        model->setHeaderData(0, Qt::Horizontal, QObject::tr("Имя"));
        model->setHeaderData(1, Qt::Horizontal, QObject::tr("Фамилия"));
        model->setHeaderData(2, Qt::Horizontal, QObject::tr("Название товара"));
        model->setHeaderData(3, Qt::Horizontal, QObject::tr("Дата оформления заказа"));
        ui->tw->setModel(model);
        delete this->model;
        this->model = model;
        ui->tw->show();
    }

5. Сумма и количество проданных товаров в торговых точках (многотабличный запрос с реализацией диалогового окна) (листинг 1.13)

Листинг 1.13 – Тип запроса «Сумма и количество проданных товаров»

Сумма и количество проданных товаров в торговых точках (многотабличный запрос с реализацией диалогового окна)

void MainWindow::on_action_14_triggered()
{
    Dialog2  dialog2;
    if (dialog2.exec())
    {
        QString p=dialog2.search();QString d=dialog2.search_2();
    QSqlError sqlError;
    QSqlQueryModel *model = new QSqlQueryModel;
    if ( d=="" ) {model->setQuery("select trade.trade_id, trade.trade_type, seller.seller_family, sum(sales.sales_price) as saleprice01, sum(sales.sales_sum) as saleprice02 from trade, seller, sales where trade.trade_id=\'"+p+"\' and trade.trade_id=seller.seller_id and seller.seller_id=sales.sales_id;") ;
        model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер торговой точки"));
        model->setHeaderData(1, Qt::Horizontal, QObject::tr("Название торговой точки"));
        model->setHeaderData(2, Qt::Horizontal, QObject::tr("Продавец точки "));
        model->setHeaderData(3, Qt::Horizontal, QObject::tr("Общая сумма проданных товаров"));
        model->setHeaderData(4, Qt::Horizontal, QObject::tr("Количество проданных товаров"));}
    if(d!=""){ model->setQuery("select trade.trade_id, trade.trade_type, seller.seller_family, sum(sales.sales_price) as saleprice01, sum(trade.trade_rent) as saleprice03 from trade, seller, sales where trade.trade_id=\'"+p+"\' and trade.trade_type=\'"+d+"\' and trade.trade_id=seller.seller_id and seller.seller_id=sales.sales_id;") ;
        model->setHeaderData(0, Qt::Horizontal, QObject::tr("Номер торговой точки"));
        model->setHeaderData(1, Qt::Horizontal, QObject::tr("Название торговой точки"));
        model->setHeaderData(2, Qt::Horizontal, QObject::tr("Продавец точки "));
        model->setHeaderData(3, Qt::Horizontal, QObject::tr("Общая сумма проданных товаров"));
        model->setHeaderData(4, Qt::Horizontal, QObject::tr("Оплата за аренду"));}
    sqlError = model->lastError();
    if (sqlError.type()!=QSqlError::NoError) {
        QMessageBox::critical(this,"SQL Error", sqlError.text());
    }
//! [3]
    ui->tw->setModel(model);
    delete this->model;
    this->model = model;
    }
}

6. Дополнительный запрос с функцией вывода на печать с сохранением текста в формате  .pdf  (листинг 1.14)

Листинг 1.14 – Тип запроса «Вывод на печать»

void MainWindow::on_action_41_triggered()
{
   ui->tw->setModel(model);     указатель модель, использованную в данный момент
    QPrinter printer;   создание класса типа Qprinter
    QTextDocument doc;   создание класса типа  QTextDocument
    QString html;   создание переменной типа QString
    QPrintDialog printDialog(&printer,this);    создание класса QPrintDialog  с параметрами  класса  QPrinter , с помощью которого  происходит вывод на печать
    if (printDialog.exec()) {
        html+="<table  bordercolor='green' border='2' width='100%'cols='10'>";
  html += "<tr>";  установка горизонтальной шапки таблицы
           for (int l=0,p=model->columnCount();l<p;++l) {
             html += "<td>" + model->headerData(l,Qt::Horizontal,0).toString() + "</td>";
           }
            html += "</tr>";

        for (int i=0,n=model->rowCount();i<n;++i) {
html += "<tr>";
            for (int j=0,m=model->columnCount();j<m;++j) {
              html += "<td>" + model->data(model->index(i,j)).toString() + "</td>";
            }
            html += "</tr>";
        }
        html+="</table>";    закрывающийся тег таблицы
        doc.setHtml(html);  выполнение функции переноса нашей таблицы в текстовый документ .doc
        printer.setOutputFormat(QPrinter::PdfFormat);  перевод в формат .pdf
        printer.setOutputFileName("example.pdf");        сохранение текста в формате pdf
        doc.print(&printer);  выполнение печати
}
}

Таким образом, основным преимуществом Qt является возможность запускать написанное приложение на большинстве современных операционных систем путём простой компиляции программы для каждой ОС без изменения исходного кода. Qt является полностью объектно-ориентированным, легко расширяемым и поддерживающим технику компонентного программирования.

Все исходные файлы проекта, курсовая работа и презентация клиентского приложения находится в прикрепленных файлах.

Читать дальше
Twitter
Одноклассники
Мой Мир

материал с la.by

2

      Add

      You can create thematic collections and keep, for instance, all recipes in one place so you will never lose them.

      No images found
      Previous Next 0 / 0
      500
      • Advertisement
      • Animals
      • Architecture
      • Art
      • Auto
      • Aviation
      • Books
      • Cartoons
      • Celebrities
      • Children
      • Culture
      • Design
      • Economics
      • Education
      • Entertainment
      • Fashion
      • Fitness
      • Food
      • Gadgets
      • Games
      • Health
      • History
      • Hobby
      • Humor
      • Interior
      • Moto
      • Movies
      • Music
      • Nature
      • News
      • Photo
      • Pictures
      • Politics
      • Psychology
      • Science
      • Society
      • Sport
      • Technology
      • Travel
      • Video
      • Weapons
      • Web
      • Work
        Submit
        Valid formats are JPG, PNG, GIF.
        Not more than 5 Мb, please.
        30
        surfingbird.ru/site/
        RSS format guidelines
        500
        • Advertisement
        • Animals
        • Architecture
        • Art
        • Auto
        • Aviation
        • Books
        • Cartoons
        • Celebrities
        • Children
        • Culture
        • Design
        • Economics
        • Education
        • Entertainment
        • Fashion
        • Fitness
        • Food
        • Gadgets
        • Games
        • Health
        • History
        • Hobby
        • Humor
        • Interior
        • Moto
        • Movies
        • Music
        • Nature
        • News
        • Photo
        • Pictures
        • Politics
        • Psychology
        • Science
        • Society
        • Sport
        • Technology
        • Travel
        • Video
        • Weapons
        • Web
        • Work

          Submit

          Thank you! Wait for moderation.

          Тебе это не нравится?

          You can block the domain, tag, user or channel, and we'll stop recommend it to you. You can always unblock them in your settings.

          • artur.baranok
          • домен la.by

          Get a link

          Спасибо, твоя жалоба принята.

          Log on to Surfingbird

          Recover
          Sign up

          or

          Welcome to Surfingbird.com!

          You'll find thousands of interesting pages, photos, and videos inside.
          Join!

          • Personal
            recommendations

          • Stash
            interesting and useful stuff

          • Anywhere,
            anytime

          Do we already know you? Login or restore the password.

          Close

          Add to collection

             

            Facebook

            Ваш профиль на рассмотрении, обновите страницу через несколько секунд

            Facebook

            К сожалению, вы не попадаете под условия акции