Guest User

Untitled

a guest
Nov 13th, 2016
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.08 KB | None | 0 0
  1. # coding: utf-8
  2.  
  3. import datetime
  4. import os
  5. import sys
  6.  
  7. from copy import copy
  8. from decimal import *
  9.  
  10. from PyQt4 import (QtGui, QtCore, QtSql, Qt)
  11. from natsort import natsorted
  12.  
  13. try:
  14.     from gui.procwin import *
  15. except ImportError:
  16.     pass
  17.  
  18. QUERIES = {
  19.     'panels': {
  20.         'query': '''
  21.            SELECT distinct isnull(panel, -1) as panel, isnull(cast(panel as varchar), 'Не задана') as panelName
  22.            FROM [Geo_Rut].[dbo].[DrillB_HEADER]
  23.            order by PANEL asc
  24.        '''
  25.     },
  26.  
  27.     'mines': {
  28.         'query': '''
  29.            SELECT n_sh as id, name
  30.            FROM [dbo].[SHA]
  31.        '''
  32.     },
  33.  
  34.     'collars': {
  35.         'query': '''
  36.            SELECT *, COUNT(*) OVER (PARTITION BY 1) as rows_count
  37.                  ,[XCOLLAR] as [EAST]
  38.                  ,[YCOLLAR] as [NORTH]
  39.                  ,[ZCOLLAR] as [RL]
  40.                  ,substring([BHID], 0, len([BHID])-1) as NAME
  41.            FROM [dbo].[MM_collars_tr]
  42.            ORDER BY BHID, DtBeg
  43.        ''',
  44.         'file_name': 'устья скважин_экспл',
  45.         'file_ext': 'dat',
  46.         'label': 'Устья скважин'
  47.     },
  48.  
  49.     'surveys': {
  50.         'query': '''
  51.            select *, count(*) over (partition by 1) as rows_count
  52.            from [dbo].[mm_surveys_tr]
  53.            where {0}
  54.        ''',
  55.         'file_name': 'инклинометрия_экспл',
  56.         'file_ext': 'dat',
  57.         'label': 'Инклинометрия'
  58.     },
  59.  
  60.     'assay': {
  61.         'query': '''
  62.            select *, count(*) over (partition by 1) as rows_count
  63.            from [dbo].[mm_assay_tr]
  64.            where {0}
  65.        ''',
  66.         'file_name': 'опробование_экпл',
  67.         'file_ext': 'dat',
  68.         'label': 'Опробование'
  69.     },
  70. }
  71.  
  72.  
  73. class SuperiorCachedSqlTableModel3000(QtCore.QAbstractTableModel):
  74.     dirty = False
  75.     _filtered = False
  76.     _data = []
  77.     _original = []
  78.     _headers = []
  79.     _uniqueValues = {}
  80.     _filterFunctions = {}
  81.     _filterString = ''
  82.     _filterColumn = ''
  83.  
  84.     def __init__(self, parent=None, model=None, populate=False):
  85.         super(SuperiorCachedSqlTableModel3000, self).__init__(parent)
  86.         if model:
  87.             self.fromSqlTableModel(model, populate)
  88.  
  89.     def getColumnName(self, index):
  90.         return self._headers[index] if index < len(self._headers) else None
  91.  
  92.     def fromSqlTableModel(self, model, populate=True):
  93.         if not isinstance(model, QtSql.QSqlTableModel):
  94.             raise Exception('Wrong model class. QSqlTableModel expected.')
  95.  
  96.         self._headers = list()
  97.         for col in range(model.columnCount()):
  98.             header = model.headerData(col,
  99.                                       QtCore.Qt.Horizontal,
  100.                                       QtCore.Qt.DisplayRole)
  101.             self._headers.append('%s' % header)
  102.             if populate:
  103.                 self._uniqueValues.update({header: set()})
  104.  
  105.         self._data = list()
  106.         for row in range(model.rowCount()):
  107.             r = list()
  108.             for col in range(model.columnCount()):
  109.                 index = model.createIndex(row, col)
  110.                 data = model.data(index)
  111.  
  112.                 if isinstance(data, (QtCore.QDateTime, QtCore.QDate)):
  113.                     data = data.toString('yyyy.MM.dd')
  114.  
  115.                 r.append(data)
  116.  
  117.                 if populate:
  118.                     self._uniqueValues[self.getColumnName(col)].add('%s' % data)
  119.  
  120.             self.addRow(r)
  121.  
  122.         self._original = copy(self._data)
  123.  
  124.         if populate:
  125.             for k, v in self._uniqueValues.items():
  126.                 self._uniqueValues[k] = natsorted(list(v))
  127.  
  128.         return
  129.  
  130.     def addRow(self, row):
  131.         self._data.append(row)
  132.  
  133.     def getRow(self, row):
  134.         if 0 <= row < len(self._data):
  135.             return self._data[row]
  136.         return []
  137.  
  138.     def getValue(self, row, columnName):
  139.         row = self.getRow(row)
  140.         column = self.fieldIndex(columnName)
  141.         if 0 <= column < len(row):
  142.             return row[column]
  143.         return None
  144.  
  145.     def rowCount(self, parent=None, *args, **kwargs):
  146.         return len(self._data)
  147.  
  148.     def columnCount(self, parent=None, *args, **kwargs):
  149.         return len(self._data[0])
  150.  
  151.     def data(self, index, role=QtCore.Qt.DisplayRole):
  152.         if not index.isValid() or \
  153.                 not (0 <= index.row() < len(self._data)):
  154.             return None
  155.         if role == QtCore.Qt.DisplayRole:
  156.             i = index.row()
  157.             j = index.column()
  158.             return '{0}'.format(self._data[i][j])
  159.         return None
  160.  
  161.     def setData(self, index, value, role=QtCore.Qt.EditRole):
  162.         if index.isValid() and 0 <= index.row() < len(self._data[0]):
  163.             column = index.column()
  164.             row = index.row()
  165.  
  166.             self._data[row][column] = value
  167.  
  168.             self.dirty = True
  169.             self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index)
  170.             return True
  171.         return False
  172.  
  173.     def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
  174.         if role != QtCore.Qt.DisplayRole:
  175.             return None
  176.         if orientation == QtCore.Qt.Horizontal:
  177.             return self._headers[section]
  178.         return int(section) + 1
  179.  
  180.     def flags(self, index):
  181.         if self.filtered():
  182.             if index.row() > 0:
  183.                 return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
  184.  
  185.             column = self.getColumnName(index.column())
  186.             if column not in self._filterFunctions.keys():
  187.                 return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
  188.  
  189.             return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable
  190.         return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
  191.  
  192.     def fieldIndex(self, field):
  193.         for i, header in enumerate(self._headers):
  194.             if header == field:
  195.                 return i
  196.         return -1
  197.  
  198.     def insertRows(self, row, count=1, parent=QtCore.QModelIndex(), *args, **kwargs):
  199.         self.beginInsertRows(QtCore.QModelIndex(), row, row + count - 1)
  200.         for r in range(count):
  201.             self._data.insert(row + r, ['' for i in range(len(self._data[0]))])
  202.             self._original.insert(row + r, ['' for i in range(len(self._data[0]))])
  203.         self.endInsertRows()
  204.         self.dirty = True
  205.         return True
  206.  
  207.     def getColumnUniqueValues(self, index=None, column=None):
  208.         if column:
  209.             return self._uniqueValues[column]
  210.  
  211.         if index >= 0:
  212.             return self._uniqueValues[self.getColumnName(index)]
  213.         return []
  214.  
  215.     def setFiltered(self, bool):
  216.         self._filtered = bool
  217.  
  218.     def filtered(self):
  219.         return self._filtered
  220.  
  221.     def filterColumn(self, index):
  222.         columnName = self.getColumnName(index)
  223.         cmpFunc = self._filterFunctions.get(columnName, None)
  224.  
  225.         if cmpFunc:
  226.             self._data = []
  227.             for row in range(len(self._original)):
  228.                 if row == 0 and self.filtered():
  229.                     self._data.append(self._original[row])
  230.                     continue
  231.                 if cmpFunc(self._filterString, '%s' % self._original[row][index]):
  232.                     self._data.append(self._original[row])
  233.             self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
  234.                       self.createIndex(0, self.columnCount()),
  235.                       self.createIndex(self.rowCount(), self.columnCount()))
  236.         return
  237.  
  238.     def setFilters(self, filters):
  239.         if not self.filtered() and len(filters):
  240.             self.insertRow(0, QtCore.QModelIndex())
  241.             self.setFiltered(True)
  242.  
  243.             for f in filters:
  244.                 column = f['column']
  245.                 cmpFunc = f['cmpFunc']
  246.                 if self.fieldIndex(column) >= 0:
  247.                     self._filterFunctions.update({column: cmpFunc})
  248.  
  249.     def setFilterString(self, string, index):
  250.         self._filterString = string
  251.         self._filterColumn = self.getColumnName(index)
  252.  
  253.  
  254. class SuperiorSqlTableView3000(QtGui.QTableView):
  255.     _filterWidget = None
  256.     _cache = None
  257.  
  258.     def __init__(self, parent, db_type, db_name, **kwargs):
  259.         super(SuperiorSqlTableView3000, self).__init__(parent)
  260.         self._db = QtSql.QSqlDatabase.addDatabase(db_type)
  261.         self._db.setDatabaseName(db_name)
  262.  
  263.         if kwargs.get('hostname', None):
  264.             self._db.setHostName(kwargs.get('hostname'))
  265.  
  266.         if kwargs.get('username', None):
  267.             self._db.setUserName(kwargs.get('username'))
  268.  
  269.         if kwargs.get('password', None):
  270.             self._db.setPassword(kwargs.get('password'))
  271.  
  272.         if not self._db.open():
  273.             error = self._db.lastError()
  274.             raise Exception('Невозможно открыть БД или нет связи с сервером! (%s, %s)' % (error.driverText(), error.databaseText()))
  275.  
  276.         self._model = QtSql.QSqlTableModel(self, self._db)
  277.         self.setSelectionBehavior(Qt.QAbstractItemView.SelectRows)
  278.         self.clicked.connect(self.onCellClicked)
  279.  
  280.     def onCellClicked(self, index):
  281.         if index.row() == 0 and self._cache.filtered():
  282.             self._filterWidget = QtGui.QComboBox(self)
  283.             self._filterWidget.setEditable(True)
  284.             self._filterWidget.addItem("")
  285.             self._filterWidget.addItems(self._cache.getColumnUniqueValues(index.column()))
  286.             self._filterWidget.editTextChanged.connect(lambda: self.onTextChanged(index))
  287.  
  288.             self.setIndexWidget(index, self._filterWidget)
  289.  
  290.     def openQuery(self, query, hideColumns=None):
  291.         # t = datetime.datetime.now()
  292.         self._model.setQuery(QtSql.QSqlQuery(query))
  293.         # print('query: ', (datetime.datetime.now()-t))
  294.  
  295.         # t = datetime.datetime.now()
  296.         self._cache = SuperiorCachedSqlTableModel3000(parent=self,
  297.                                                       model=self._model,
  298.                                                       populate=True)
  299.         # print('caching: ',  (datetime.datetime.now()-t))
  300.  
  301.         self.setModel(self._cache)
  302.         self.hideColumns(hideColumns)
  303.         self.resizeColumns()
  304.         return
  305.  
  306.     def onTextChanged(self, index):
  307.         widget = self.indexWidget(index)
  308.         self._cache.setFilterString(widget.currentText(), index.column())
  309.         self._cache.filterColumn(index.column())
  310.  
  311.     def setFilters(self, filters):
  312.         if self._cache is not None:
  313.             self._cache.setFilters(filters)
  314.  
  315.     def resizeColumns(self):
  316.         magic = 25
  317.         self.resizeColumnsToContents()
  318.         for i in range(0, self._cache.columnCount()):
  319.             self.setColumnWidth(i, self.columnWidth(i) + magic)
  320.         return
  321.  
  322.     def hideColumns(self, columns=()):
  323.         if columns:
  324.             for column in columns:
  325.                 self.hideColumn(self._cache.fieldIndex(column))
  326.  
  327.  
  328. class GeoPointsFilterForm(QtGui.QWidget):
  329.     def __init__(self, **kwargs):
  330.         super(GeoPointsFilterForm, self).__init__(**kwargs)
  331.  
  332.         self.window_init()
  333.  
  334.         # self.view = SuperiorSqlTableView3000(self, 'QODBC', 'DRIVER={SQL Server};Server=ggs;Database=GEO_RUT')
  335.         self.view = SuperiorSqlTableView3000(self, 'QPSQL', 'rog', hostname='localhost', port='5432', username='postgres', password='72946.penta')
  336.         self.view.openQuery("select id, posting_date, title, slug from news_news order by id;", hideColumns=['slug'])
  337.  
  338.         # self.view.setFilters([])
  339.  
  340.         self.view.setFilters([
  341.             {
  342.                 'column': 'id',
  343.                 'cmpFunc': lambda sample, value: sample.lower() in value.lower()
  344.             },
  345.             {
  346.                 'column': 'posting_date',
  347.                 'cmpFunc': lambda sample, value: sample <= value
  348.             },
  349.         ])
  350.  
  351.         self.view.resize(1024, 600)
  352.         self.view.move(0, 0)
  353.  
  354.         self.show()
  355.  
  356.     def window_init(self):
  357.         self.setFixedSize(1024, 600)
  358.         self.setWindowTitle('Скважины')
  359.  
  360. app = QtGui.QApplication(sys.argv)
  361. window = GeoPointsFilterForm()
  362. sys.exit(app.exec_())
Add Comment
Please, Sign In to add comment