def mimeData(self, indexes): """Returns a QMimeData object that contains serialized items of data corresponding to the list of indexes specified. When a node is dragged the information required to drop it later on is encoded by this method and returned as a QMimeData object. :Parameter indexes: a list of indexes """ mime_data = QtCore.QMimeData() encoded_data = QtCore.QByteArray() stream = QtCore.QDataStream(encoded_data, QtCore.QIODevice.WriteOnly) # Only one item selections are allowed in the tree of databases # view so indexes contains always one element for index in indexes: if index.isValid(): filepath = self.data(index, QtCore.Qt.UserRole) nodepath = self.data(index, QtCore.Qt.UserRole + 1) row = str(index.row()) stream.writeQString(filepath) stream.writeQString(nodepath) stream.writeQString(row) self.initial_parent = self.parent(index) # Store the MIME type of the object and the encoded description of that # object in the QMimeData object mime_data.setData("application/x-dbstreemodeldatalist", encoded_data) return mime_data
def decodeMimeData(self, data): result = {} stream = QtCore.QDataStream(data) while not stream.atEnd(): row = stream.readInt32() stream.readInt32() # Column; not used item = result.setdefault(row, {}) for role in range(stream.readInt32()): key = QtCore.Qt.ItemDataRole(stream.readInt32()) item[key] = stream.readQVariant() return result
def __setstate__(self, ba): stream = QtCore.QDataStream(ba, QtCore.QIODevice.ReadOnly) stream >> self
def __getstate__(self): ba = QtCore.QByteArray() stream = QtCore.QDataStream(ba, QtCore.QIODevice.WriteOnly) stream << self return ba
def dropMimeData(self, data, action, row, column, parent): """Handles the data supplied by a drag and drop operation that ended with the given action. :Parameters: - `data`: the data being dropped. - `action`: the action being performed (copy or move). - `row`: the row under the item where the operation ends. - `columns`: the column under the item where the operation ends. - `parent`: the index of the item where operation ends. :Returns: True if item is dropped. Otherwise it returns False. """ # Examine the MIME type if not (data.hasFormat("application/x-dbstreemodeldatalist") or data.hasFormat("text/uri-list")): return False if action == QtCore.Qt.IgnoreAction: return True if column > 0: return False # If the dropped object is one or more files then open them if data.hasFormat("text/uri-list"): uris_list = data.urls() # Transform every element of the sequence into a path and open it for uri in uris_list: path = uri.path() if sys.platform.startswith('win'): path = path[1:] if os.path.isfile(path): self.vtapp.fileOpen(path) return True # If the dropped object is a tree node then update the tree parent_node = self.nodeFromIndex(parent) encoded_data = data.data("application/x-dbstreemodeldatalist") # Moving is not allowed if the parent group remains the same initial_parent = self.initial_parent if parent == initial_parent: return False stream = QtCore.QDataStream(encoded_data, QtCore.QIODevice.ReadOnly) while not stream.atEnd(): # Decode the encoded data filepath = stream.readQString() nodepath = stream.readQString() initial_row = int(stream.readQString()) # A node cannot be moved on itself if (parent_node.filepath, parent_node.nodepath) == (filepath, nodepath): return False # Move the node to its final destination in the PyTables database new_name = self.move_node(filepath, nodepath, parent) if new_name is None: return False # Remove the dragged node from the model self.remove_rows(initial_row, parent=initial_parent) # If needed, refresh the copied node info try: if self.ccni['filepath'] == filepath: if self.ccni['nodepath'].startswith(nodepath): self.ccni = {} except KeyError: pass # Add the dropped node to the model self.lazyAddChildren(parent) parent_node.updated = True # Select the pasted node self.selectIndex(parent, new_name) return True
def __setstate__(self, ba): stream = QtCore.QDataStream(ba, QtCore.QIODevice.ReadOnly) px = QtGui.QPixmap() stream >> px super().__init__(px)
def __getstate__(self): ba = QtCore.QByteArray() stream = QtCore.QDataStream(ba, QtCore.QIODevice.WriteOnly) pixmap = self.pixmap(QtCore.QSize(256, 256)) stream << pixmap return ba
def arrayToQPath(x, y, connect='all'): """Convert an array of x,y coordinats to QPainterPath as efficiently as possible. The *connect* argument may be 'all', indicating that each point should be connected to the next; 'pairs', indicating that each pair of points should be connected, or an array of int32 values (0 or 1) indicating connections. """ #CODE IS COPIED FROM PYQTGRAPH ## Create all vertices in path. The method used below creates a binary format so that all ## vertices can be read in at once. This binary format may change in future versions of Qt, ## so the original (slower) method is left here for emergencies: #path.moveTo(x[0], y[0]) #if connect == 'all': #for i in range(1, y.shape[0]): #path.lineTo(x[i], y[i]) #elif connect == 'pairs': #for i in range(1, y.shape[0]): #if i%2 == 0: #path.lineTo(x[i], y[i]) #else: #path.moveTo(x[i], y[i]) #elif isinstance(connect, np.ndarray): #for i in range(1, y.shape[0]): #if connect[i] == 1: #path.lineTo(x[i], y[i]) #else: #path.moveTo(x[i], y[i]) #else: #raise Exception('connect argument must be "all", "pairs", or array') ## Speed this up using >> operator ## Format is: ## numVerts(i4) 0(i4) ## x(f8) y(f8) 0(i4) <-- 0 means this vertex does not connect ## x(f8) y(f8) 1(i4) <-- 1 means this vertex connects to the previous vertex ## ... ## 0(i4) ## ## All values are big endian--pack using struct.pack('>d') or struct.pack('>i') path = QtGui.QPainterPath() #profiler = debug.Profiler() n = x.shape[0] # create empty array, pad with extra space on either end arr = np.empty(n + 2, dtype=[('x', '>f8'), ('y', '>f8'), ('c', '>i4')]) # write first two integers #profiler('allocate empty') byteview = arr.view(dtype=np.ubyte) byteview[:12] = 0 byteview.data[12:20] = struct.pack('>ii', n, 0) #profiler('pack header') # Fill array with vertex values arr[1:-1]['x'] = x arr[1:-1]['y'] = y # decide which points are connected by lines #I replaced eq function by == if connect == 'all': arr[1:-1]['c'] = 1 elif connect == 'pairs': arr[1:-1]['c'][::2] = 1 arr[1:-1]['c'][1::2] = 0 elif connect == 'finite': arr[1:-1]['c'] = np.isfinite(x) & np.isfinite(y) elif isinstance(connect, np.ndarray): arr[1:-1]['c'] = connect else: raise Exception( 'connect argument must be "all", "pairs", "finite", or array') #profiler('fill array') # write last 0 lastInd = 20 * (n + 1) byteview.data[lastInd:lastInd + 4] = struct.pack('>i', 0) #profiler('footer') # create datastream object and stream into path ## Avoiding this method because QByteArray(str) leaks memory in PySide #buf = QtCore.QByteArray(arr.data[12:lastInd+4]) # I think one unnecessary copy happens here path.strn = byteview.data[12:lastInd + 4] # make sure data doesn't run away try: buf = QtCore.QByteArray.fromRawData(path.strn) except TypeError: buf = QtCore.QByteArray(bytes(path.strn)) #profiler('create buffer') ds = QtCore.QDataStream(buf) ds >> path #profiler('load') return path