#!/usr/bin/env python # vim: set expandtab tabstop=4 shiftwidth=4: # PyQt Functionality Snippet by Apocalyptech # "Licensed" in the Public Domain under CC0 1.0 Universal (CC0 1.0) # Public Domain Dedication. Use it however you like! # # https://creativecommons.org/publicdomain/zero/1.0/ # https://creativecommons.org/publicdomain/zero/1.0/legalcode import sys from PyQt5 import QtWidgets, QtGui, QtCore class MyModel(QtGui.QStandardItemModel): def dropMimeData(self, data, action, row, col, parent): """ Always move the entire row, and don't allow column "shifting" """ return super().dropMimeData(data, action, row, 0, parent) class MyStyle(QtWidgets.QProxyStyle): def drawPrimitive(self, element, option, painter, widget=None): """ Draw a line across the entire row rather than just the column we're hovering over. This may not always work depending on global style - for instance I think it won't work on OSX. """ if element == self.PE_IndicatorItemViewItemDrop and not option.rect.isNull(): option_new = QtWidgets.QStyleOption(option) option_new.rect.setLeft(0) if widget: option_new.rect.setRight(widget.width()) option = option_new super().drawPrimitive(element, option, painter, widget) class MyTableView(QtWidgets.QTableView): def __init__(self, parent): super().__init__(parent) self.verticalHeader().hide() self.horizontalHeader().hide() self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) self.setSelectionBehavior(self.SelectRows) self.setSelectionMode(self.SingleSelection) self.setShowGrid(False) self.setDragDropMode(self.InternalMove) self.setDragDropOverwriteMode(False) # Set our custom style - this draws the drop indicator across the whole row self.setStyle(MyStyle()) # Set our custom model - this prevents row "shifting" self.model = MyModel() self.setModel(self.model) for (idx, data) in enumerate(['foo', 'bar', 'baz']): item_1 = QtGui.QStandardItem('Item {}'.format(idx)) item_1.setEditable(False) item_1.setDropEnabled(False) item_2 = QtGui.QStandardItem(data) item_2.setEditable(False) item_2.setDropEnabled(False) self.model.appendRow([item_1, item_2]) class Testing(QtWidgets.QMainWindow): def __init__(self): super().__init__() # Main widget w = QtWidgets.QWidget() l = QtWidgets.QVBoxLayout() w.setLayout(l) self.setCentralWidget(w) # spacer l.addWidget(QtWidgets.QLabel('top'), 1) # Combo Box l.addWidget(MyTableView(self)) # spacer l.addWidget(QtWidgets.QLabel('bottom'), 1) # A bit of window housekeeping self.resize(400, 400) self.setWindowTitle('Testing') self.show() if __name__ == '__main__': app = QtWidgets.QApplication([]) test = Testing() sys.exit(app.exec_())