I'm trying to create a QListView with QStyledItemDelegate to show data more organizing way.
I gone through this site, and its all in C++, and I have no idea about it, guessing from the syntax and calls which has been used in the post, I tried my way to achieve it, but I had not luck. Can someone please help me out with this?
import sys, os
from PyQt4 import QtGui, QtCore
class ListView(QtGui.QListView):
def __init__(self, parent=None):
super(ListView, self).__init__(parent)
self._model = None
self._data = [
[
'Header: King Arthur',
'Project: TBN',
'Asset: arthur',
'Task name: Design doc',
'Start Date: Today',
'End Date: Next Monday'
]
]
self.set_model()
item_delegate = ItemDelegate()
self.setItemDelegate(item_delegate)
self.openPersistentEditor(self._model.createIndex(0, 0))
def set_model(self):
self._model = ListModel(self._data, parent=self)
self.setModel(self._model)
class ListModel(QtCore.QAbstractItemModel):
def __init__(self, data=[], parent=None):
super(ListModel, self).__init__(parent)
self._data = data
def rowCount(self, *arg):
return 1
def columnCount(self, *arg):
return len(self._data)
def data(self, index, role):
row = index.row()
column = index.column()
if role == QtCore.Qt.DisplayRole:
return QtCore.QVariant(' | '.join(self._data[column]))
return QtCore.QVariant()
def index(self, row, column, parent):
return self.createIndex(row, column)
def parent(self, index):
item = index.internalPointer()
if item:
return item.getParent()
else:
item = self.createIndex(index.row(), index.column()).internalPointer()
if item:
return item.getParent()
return QtCore.QModelIndex()
class ItemDelegate(QtGui.QStyledItemDelegate):
def createEditor(self, parent, option, index):
item_data = str(index.data().toString())
editor = Widget(item_data.split('|'), parent=parent)
return editor
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
class Widget(QtGui.QWidget):
def __init__(self, widget_data=[], parent=None):
super(Widget, self).__init__(parent)
vbox = QtGui.QVBoxLayout(self)
key_font = QtGui.QFont()
key_font.setWeight(QtGui.QFont.Bold)
val_font = QtGui.QFont()
val_font.setWeight(QtGui.QFont.Normal)
for each_data in widget_data:
hbox = QtGui.QHBoxLayout()
key, value = each_data.split(':')
key_text = QtGui.QLabel(self)
val_text = QtGui.QLabel(self)
key_text.setToolTip('Key: %s' % key)
val_text.setToolTip('Value: %s' % value)
key_text.setText(key)
val_text.setText(value)
key_text.setFont(key_font)
val_text.setFont(val_font)
hbox.addWidget(key_text)
hbox.addWidget(val_text)
# vbox.addLayout(hbox)
if __name__ == '__main__':
qapp = QtGui.QApplication([])
app = ListView()
app.show()
sys.exit(qapp.exec_())
Unless you have a compelling reason to use the View/Model pattern, in most cases it's going to be easier to use the Widget/Item pattern -- QListWidget and QListWidgetItem.
The QItemDelegate and QStyledItemDelegate are designed to be subclassed. You then define methods that are responsible for handling events, sizing, and painting the views/widgets.
class MyWidget(QtGui.QWidget):
def __init__(self, parent):
super(MyWidget, self).__init__(parent)
self.listwidget = QtGui.QListWidget(self)
self.delegate = MyDelegate(self, self.listwidget)
self.listwidget.setItemDelegate(self.delegate)
datas = [
{'Header': 'Blah', 'Project': 'TBN'},
{'Header': 'Other', 'Project': 'Something'},
]
for data in datas:
MyItem(self.listwidget, data)
class MyItem(QtGui.QListWidgetItem):
def __init__(self, parent, data):
super(MyItem, self).__init__(parent)
self._data = data
class MyDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent, listwidget):
super(MyDelegate, self).__init__(parent)
self.listwidget = listwidget
def sizeHint(self, option, index):
if index:
item = self.listwidget.itemFromIndex(index)
print item._data
# Do fontmetrics stuff from C++ article you linked
# using the text in the data dictionary.
def paint(self, painter, option, index):
# same thing, get the item using the index
# get the data from the item
# paint the data however you want.
class ItemDelegate(QtGui.QStyledItemDelegate):
def createEditor(self, parent, option, index):
item_data = str(index.data().toString())
editor = Widget(item_data.split('|'), parent=parent)
return editor
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
def paint(self, painter, option, index):
painter.save()
index.model().setData(index, option.rect.width(), Qt.UserRole+1)
fixed this issue
Related
I got the following problem:
I have a GUI with a qtableview, a generic delegate (as in the book of Marc Summerfield) and a datamodel for that.
I designed a Dialog which shows up, if i want to change certain columns. There is a label, a combobox and a button in the dialog.
Until now, everything works fine, selection can be done, data can be processed.
But there is no possibility to set the position where the dialog pops up. So sometimes it is simply un-operatable (almost off the screen and so on)
So my question:
How can I set the position, where the dialog pops up?
Minimum example:
The generic delegate
class GenericDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
super(GenericDelegate, self).__init__(parent)
self.delegates = {}
def insertColumnDelegate(self, column, delegate, **kwargs):
delegate.setParent(self)
self.delegates[column] = delegate
def removeColumnDelegate(self, column):
if column in self.delegates:
del self.delegates[column]
def paint(self, painter, option, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
delegate.paint(painter, option, index)
else:
QItemDelegate.paint(self, painter, option, index)
def createEditor(self, parent, option, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
return delegate.createEditor(parent, option, index)
else:
return QStyledItemDelegate.createEditor(self, parent, option, index)
def setEditorData(self, editor, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
delegate.setEditorData(editor, index)
else:
QStyledItemDelegate.setEditorData(self, editor, index)
def setModelData(self, editor, model, index):
delegate = self.delegates.get(index.column())
if delegate is not None:
delegate.setModelData(editor, model, index)
else:
QStyledItemDelegate.setModelData(self, editor, model, index)
def setDelegateData(self, index, data):
delegate = self.delegates.get(index.column())
if delegate is not None and hasattr(delegate, "setDelegateData"):
delegate.setDelegateData(data)
else:
pass
The columns delegate
class ComboBoxColumnDelegate(QStyledItemDelegate):
def __init__(self, dialog, editordata=[], parent=None, target="Folder"):
super().__init__(parent)
self.editor = dialog
self.parent = parent
self.editordata = editordata
self.target = target
def createEditor(self, parent, option, index):
editor = self.editor(parent=self.parent, target = self.target, values=self.editordata)
return editor
def setDelegateData(self, data = {}):
if not data:
return 0
for key, value in data.items():
if hasattr(self, key):
setattr(self, key, value)
def setEditorData(self, editor, index):
editor.setData(self.editordata)
def setModelData(self, editor, model, index):
if editor.result() == QDialog.Accepted:
model.setData(index, editor.selectedChoice(), Qt.EditRole)
For the dialog, a normal QDialog can be taken, since only the position of it matters.
In the mainwindow I initialize the delegate:
class mw(QMainWindow)
def __init(self, parent=None):
super(mw, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self._init_testtablemodel()
....
def _init_testtablemodel(self):
self.testmodel = testtablemodel(self)
self.ui.tableView_tests.setModel(self.testmodel)
# generic delegate
test_delegate = GenericDelegate()
# Insert the delegates for the columns
test_delegate.insertColumnDelegate(0, ComboboxColumnDelegate())
...
self.ui.tableView_tests.setItemDelegate(test_delegate)
The model is as recommended:
class testtablemodel(QAbstractTableModel)
def __init__(self, parent=None)
...
def rowCount(self, index):
...
def columnCount(self, index):
...
def data(self, index, role):
...
def setData(self, index, value, role):
...
def headerData(self, section, orientation, role):
...
def flags(self, index):
...
...
As mentioned befor, all data processing works perfectly nice, but the position of the editor poping up is bad.
I hope, the basic structure of the program is understandable.
Edit:
Changed the QItemDelegate to QStyledItemDelegate, which works as well and makes no difference so far.
This code I have taken from https://bravo.hatenablog.jp/entry/2016/01/18/093059 .
In this I want to add header "Quantity" at run time if needed.
Before creating table it should ask for how many headers? If user supply 4 then create table with "Quantity" headers also. Otherwise create default headers (Three).
I have tried it but not found any solution.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Model(QAbstractItemModel):
headers = "Toppings", "Udon/Soba", "Hot/Cold"
def __init__(self, parent=None):
super(Model, self).__init__(parent)
self.items = []
def index(self, row, column, parent=QModelIndex()):
return self.createIndex(row, column, None)
def parent(self, child):
return QModelIndex()
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return len(self.headers)
def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
try:
return self.items[index.row()][index.column()]
except:
return
return
def headerData(self, section, orientation, role=Qt.DisplayRole):
if role != Qt.DisplayRole:
return
if orientation == Qt.Horizontal:
return self.headers[section]
def addRow(self, topping, menkind, hotcold):
self.beginInsertRows(QModelIndex(), len(self.items), 1)
self.items.append([topping, menkind, hotcold])
self.endInsertRows()
def removeRows(self, rowIndexes):
for row in sorted(rowIndexes, reverse=True):
self.beginRemoveRows(QModelIndex(), row, row + 1)
del self.items[row]
self.endRemoveRows()
def flags(self, index):
return super(Model, self).flags(index) | Qt.ItemIsEditable
def setData(self, index, value, role=Qt.EditRole):
if role == Qt.EditRole:
self.items[index.row()][index.column()] = value
return True
return False
class View(QTreeView):
def __init__(self, parent=None):
super(View, self).__init__(parent)
self.setItemsExpandable(False)
self.setIndentation(0)
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
def drawBranches(self, painter, rect, index):
return
class InputWidget(QWidget):
def __init__(self, parent=None):
super(InputWidget, self).__init__(parent)
layout = QVBoxLayout()
toppings = ("Kitsune", "Tanuki", "Tempura", "Tsukimi", "Meat", "Curry")
self.toppingInput = QComboBox()
for topping in toppings:
self.toppingInput.addItem(topping)
layout.addWidget(self.toppingInput)
self.bgrp = QGroupBox()
udon = QRadioButton('Udon')
udon.setChecked(True)
soba = QRadioButton('Soba')
btnlayout = QHBoxLayout()
btnlayout.addWidget(udon)
btnlayout.addWidget(soba)
self.bgrp.setLayout(btnlayout)
layout.addWidget(self.bgrp)
self.udonsoba = udon, soba
self.bgrp_temp = QGroupBox()
hot = QRadioButton('Warm')
hot.setChecked(True)
cold = QRadioButton('Cold')
btnlayout_temp = QHBoxLayout()
btnlayout_temp.addWidget(hot)
btnlayout_temp.addWidget(cold)
self.bgrp_temp.setLayout(btnlayout_temp)
layout.addWidget(self.bgrp_temp)
self.hotcold = hot, cold
self.addButton = QPushButton('OK')
layout.addWidget(self.addButton)
layout.addStretch()
self.setLayout(layout)
def values(self):
topping = self.toppingInput.currentText()
udonsoba = '?'
for btn in self.udonsoba:
if btn.isChecked():
udonsoba = btn.text()
break
hotcold = '?'
for btn in self.hotcold:
if btn.isChecked():
hotcold = btn.text()
break
return topping, udonsoba, hotcold
class Delegate(QStyledItemDelegate):
def __init__(self, parent=None):
super(Delegate, self).__init__(parent)
def createEditor(self, parent, option, index):
return QLineEdit(parent)
def setEditorData(self, editor, index):
value = index.model().data(index, Qt.DisplayRole)
editor.setText(value)
def setModelData(self, editor, model, index):
model.setData(index, editor.text())
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.view = View(self)
self.model = Model(self)
self.view.setModel(self.model)
self.view.setItemDelegate(Delegate())
self.setCentralWidget(self.view)
self.inputWidget = InputWidget()
self.inputWidget.addButton.clicked.connect(self.addItem)
self.addDock = QDockWidget('Input', self)
self.addDock.setWidget(self.inputWidget)
self.addDock.setAllowedAreas(Qt.AllDockWidgetAreas)
self.addDockWidget(Qt.RightDockWidgetArea, self.addDock)
self.addDock.hide()
toolBar = QToolBar()
self.addToolBar(toolBar)
delButton = QPushButton('Delete')
delButton.clicked.connect(self.removeItems)
toolBar.addWidget(delButton)
self.addButton = QPushButton('Add')
self.addButton.clicked.connect(self.addDock.show)
toolBar.addWidget(self.addButton)
def addItem(self):
self.model.addRow(*self.inputWidget.values())
def selectedRows(self):
rows = []
for index in self.view.selectedIndexes():
if index.column() == 0:
rows.append(index.row())
return rows
def removeItems(self):
self.model.removeRows(self.selectedRows())
def main():
app = QApplication(sys.argv)
w = MainWindow()
w.show()
w.raise_()
app.exec_()
if __name__ == '__main__':
main()
I'm creating a custom item delegate for a news feed I'm trying to create in pyside. I'm not quite sure how to make the textEdit auto adjust it's size to fit the contents of the text it's wrapping and secondly maintain the Text Interaction feature, where users can click and highlight text?
This is what I'm currently getting and you can see the text boxes are being drawn overtop and not vertically being sized correctly:
import os, sys
from Qt import QtWidgets, QtCore, QtGui
class NewsItem(object):
def __init__(self, **kwargs):
super(NewsItem, self).__init__()
self.title = kwargs.get('title', '')
self.date = kwargs.get('date', '')
self.content = kwargs.get('content', '')
class NewsItemDelegate(QtWidgets.QItemDelegate):
def __init__(self, parent=None):
super(NewsItemDelegate, self).__init__(parent)
def paint(self, painter, option, index):
# rect = option.rect.adjusted(1, 1, -1, -1)
# painter.fillRect(rect, QtGui.QColor(20,40,170,50))
# QtWidgets.QItemDelegate.paint(self, painter, option, index)
# get data from userrole
data = index.data(role=QtCore.Qt.UserRole)
# Main Widget
title = QtWidgets.QLabel(data.title)
content = QtWidgets.QTextEdit(data.content)
content.setFixedHeight(content.sizeHint().height())
widget = QtWidgets.QWidget()
layout = QtWidgets.QGridLayout(widget)
layout.addWidget(title, 0, 0)
layout.addWidget(content, 1, 0)
widget.setGeometry(option.rect)
widget.render(painter, option.rect.topLeft())
# painter.save()
# painter.restore()
def sizeHint(self, option, index):
return QtCore.QSize(100, 50)
return QtWidgets.QItemDelegate.sizeHint(self, option, index)
class NewsModel(QtGui.QStandardItemModel):
def __init__(self, *args, **kwargs):
QtGui.QStandardItemModel.__init__(self, *args, **kwargs)
class NewsListView(QtWidgets.QListView):
def __init__(self, parent=None):
super(NewsListView, self).__init__(parent)
self.setModel(NewsModel(self))
self.setItemDelegate(NewsItemDelegate(self))
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
def setNewsItems(self, lst):
self.model().clear()
for x in lst:
item = QtGui.QStandardItem()
# item.setData(x.title, role=QtCore.Qt.DisplayRole)
item.setData(x, role=QtCore.Qt.UserRole)
self.model().appendRow(item)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.resize(350, 500)
# Controls
self.uiListView = NewsListView()
self.setCentralWidget(self.uiListView)
def unitTest(self):
self.uiListView.setNewsItems([
NewsItem(title='Big Update', date='Today', content='Something goes here...'),
NewsItem(title='Smaller Update', date='Yesterday', content='Something goes here which should support word wrap'),
NewsItem(title='Another Update', date='Last Year', content='Something goes here...'),
NewsItem(title='Old Update', date='Unknown', content='Something goes here...'),
])
def main():
app = QtWidgets.QApplication(sys.argv)
ex = MainWindow()
ex.unitTest()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
In this type of cases is to create a widget as an editor, and for this you must make in the paint method call openPersistentEditor(). The createEditor(), setEditorData() and setModelData() methods must also be overwritten.
# ...
from functools import partial
# ...
class EditorWidget(QtWidgets.QWidget):
editingFinished = QtCore.Signal()
def __init__(self, data=None, parent=None):
super(EditorWidget, self).__init__(parent)
self.title_label = QtWidgets.QLabel()
self.content_textedit = QtWidgets.QTextEdit()
self.content_textedit.textChanged.connect(self.editingFinished)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.title_label)
lay.addWidget(self.content_textedit)
if data is not None:
self.data = data
#property
def data(self):
return NewsItem(
title=self.title_label.text(),
content=self.content_textedit.toPlainText(),
)
#data.setter
def data(self, d):
self.title_label.setText(d.title)
tc = self.content_textedit.textCursor()
self.content_textedit.setPlainText(d.content)
self.content_textedit.setTextCursor(tc)
class NewsItemDelegate(QtWidgets.QItemDelegate):
def paint(self, painter, option, index):
if isinstance(self.parent(), QtWidgets.QAbstractItemView):
self.parent().openPersistentEditor(index)
def createEditor(self, parent, option, index):
data = index.data(QtCore.Qt.UserRole)
editor = EditorWidget(data, parent)
wrapper = partial(self.commitData.emit, editor)
editor.editingFinished.connect(wrapper)
model = index.model()
model.setData(index, editor.sizeHint(), QtCore.Qt.SizeHintRole)
return editor
def setEditorData(self, editor, index):
data = index.data(QtCore.Qt.UserRole)
editor.data = data
def setModelData(self, editor, model, index):
model.setData(index, editor.data, QtCore.Qt.UserRole)
# ...
When one of the QTableView's QModelIndex is clicked I want to select an entire row of the same-row-indexes.
To accomplish this I connect QTableView's clicked signal to a custom viewClicked() method which receives the clicked QModelIndex automatically:
self.tableview=QTableView()
self.tableview.clicked.connect(self.viewClicked)
Inside of viewClicked(self, clickedIndex) I query clickedIndex's row number, its model and the total number of columns):
row=clickedIndex.row()
model=clickedIndex.model()
columnsTotal=model.columnCount(None)
Finally to select an every index in a row:
for i in range(columnsTotal): self.tableview.selectRow(row)
The problem is it is noticeably slow for Qt to process such an action.
I wonder if there is a faster way to select an entire row of indexes when one of the tableview items is clicked:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def rowCount(self, parent):
return 1
def columnCount(self, parent):
return len(self.items)
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
column=index.column()
if column<len(self.items):
return QVariant(self.items[column])
else:
return QVariant()
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
tablemodel=Model(self)
self.tableview=QTableView()
self.tableview.setModel(tablemodel)
self.tableview.clicked.connect(self.viewClicked)
layout = QHBoxLayout(self)
layout.addWidget(self.tableview)
self.setLayout(layout)
def viewClicked(self, clickedIndex):
row=clickedIndex.row()
model=clickedIndex.model()
columnsTotal=model.columnCount(None)
for i in range(columnsTotal):
self.tableview.selectRow(row)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
EDITED LATER: REVISED WORKING CODE Thanks to Nejat! :
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def rowCount(self, parent):
return 1
def columnCount(self, parent):
return len(self.items)
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
column=index.column()
if column<len(self.items):
return QVariant(self.items[column])
else:
return QVariant()
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
tablemodel=Model(self)
self.tableview=QTableView()
self.tableview.setModel(tablemodel)
self.tableview.clicked.connect(self.viewClicked)
self.tableview.setSelectionBehavior(QTableView.SelectRows)
layout = QHBoxLayout(self)
layout.addWidget(self.tableview)
self.setLayout(layout)
def viewClicked(self, clickedIndex):
row=clickedIndex.row()
model=clickedIndex.model()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
You can use setSelectionBehavior function of QTableView to set the selection behavior to QTableView.SelectRows :
self.tableview.setSelectionBehavior(QTableView.SelectRows);
Now when you click on an item, the entire row is selected.
I want to make the first column with checkbox, and get the check status of that, how can I do that? I override the flag(), but it seems do not work, I am sure where is the problem?
And I got this links, but it does work for my code either. And I don't want to use delegate, because it is too complicated.
data = [['00','01','02'],
['10','11','12'],
['20','21','22']]
class MainWindow(QWidget):
def __init__(self, parent=None, *args):
super(MainWindow, self).__init__(parent)
clipTableWidget = QTableWidget()
self.model = TModel(data, self)
clipTableView = QTableView()
clipTableView.setModel(self.model)
layout = QVBoxLayout()
layout.addWidget(clipTableView)
self.setLayout(layout)
class TModel(QAbstractTableModel):
def __init__(self, datain, parent=None):
super(TModel, self).__init__(parent)
self.arraydata = datain
def rowCount(self, parent=QModelIndex()):
return len(self.arraydata)
def columnCount(self, parent=QModelIndex()):
return len(self.arraydata[0])
def data(self, index, role):
if not index.isValid():
return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
return QVariant(self.arraydata[index.row()][index.column()])
def flags(self, index):
if not index.isValid():
return QVariant()
elif index.column() == 1:
return Qt.ItemIsSelectable|Qt.ItemIsEnabled|Qt.ItemIsUserCheckable
return QVariant()
Ok here is the solution to your problem. The reason Why your flags weren't working is because those flags dont work on text , they are meant for QItems .
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class MainWindow(QWidget):
def __init__(self, parent=None, *args):
super(MainWindow, self).__init__(parent)
data = [['00','01','02'],
['10','11','12'],
['20','21','22']]
clipTableWidget = QTableWidget()
self.model = QStandardItemModel(self)
clipTableView = QTableView()
count1=0
for row in data:
count2 = 0
for column in row:
if count2 == 0:
item = QStandardItem(column)
item.setCheckable(True)
item.setCheckState(False)
item.setFlags(Qt.ItemIsUserCheckable| Qt.ItemIsEnabled)
self.model.setItem(count1,count2,item)
count2+=1
else:
item = QStandardItem(column)
self.model.setItem(count1,count2,item)
count2+=1
count1+=1
clipTableView.setModel(self.model)
layout = QVBoxLayout()
layout.addWidget(clipTableView)
self.setLayout(layout)
def main():
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()