get all the data treeview? - pyqt4

I need to get all the rows in an array.
As it is, this code returns all the data from the treeview and all the items in array from the treeview. I don't think I have the correct method; how can I fix this?
from PyQt4 import QtGui, QtCore
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.model = QtGui.QStandardItemModel()
self.view = QtGui.QTreeView()
#self.view.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.view.setModel(self.model)
self.setCentralWidget(self.view)
#parent = self.model.invisibleRootItem()
self.model.setHorizontalHeaderLabels(["Referencia","Nombre","Costo","UND","Precio"])
for item in '1234 name 9999 10000'.split():
self.model.appendRow([QtGui.QStandardItem(item),QtGui.QStandardItem(item),QtGui.QStandardItem(item),
QtGui.QStandardItem(item),QtGui.QStandardItem(item),
])
#self.view.setColumnWidth(0,50)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

model = tableView.model()
data = []
for row in range(model.rowCount()):
data.append([])
for column in range(model.columnCount()):
index = model.index(row, column)
data[row].append(str(model.data(index).toString()))

Related

How to select row on cursor move?

I want to imitate list walking with arrow keys, I mean to select row when cursor goes up or down with arrow keys, like it happens when I click right-mouse-button on cell in this code, but keyPressEvent does not fires when I use arrows keys.
import sys
from PySide6 import QtCore
from PySide6.QtGui import QKeyEvent
from PySide6.QtWidgets import QMainWindow, QApplication, QTableWidgetItem, QTableWidget, QVBoxLayout, QWidget
from loguru import logger
class TableWindow(QMainWindow):
def __init__(self, data, parent=None):
super(TableWindow, self).__init__(parent)
self.table_widget = QTableWidget()
self.table_widget.cellClicked.connect(self.clicked)
self.populate_cells(data)
layout = QVBoxLayout()
layout.addWidget(self.table_widget)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def keyPressEvent(self, event) -> None:
logger.info(f"{event.key()=}")
def clicked(self, row, col):
logger.info(f"{row}, {col}")
self.table_widget.selectRow(row)
def populate_cells(self, data):
self.table_widget.setRowCount(len(data))
self.table_widget.setColumnCount(len(data[0]))
for row in range(len(data)):
for col in range(len(data[0])):
value = data[row][col]
self.table_widget.setItem(row, col, QTableWidgetItem(value))
if __name__ == "__main__":
data_sample = [
["customer1", "address1"],
["customer2", "address2"]
]
app = QApplication(sys.argv)
window = TableWindow(data_sample)
window.show()
sys.exit(app.exec())
I think the issue is that you are listening for keyPressEvents on the main window when you want to be listening for them on the QTableWidget.
What you can do is subclass QTableWidget and reimplement the keyPressEvent method.
For Example:
class TableWidget(QTableWidget):
def keyPressEvent(self, event):
logger.info(f"{event.key()=}")
super().keyPressEvent(event)
class TableWindow(QMainWindow):
def __init__(self, data, parent=None):
super(TableWindow, self).__init__(parent)
self.table_widget = TableWidget()
self.table_widget.cellClicked.connect(self.clicked)
self.populate_cells(data)
layout = QVBoxLayout()
layout.addWidget(self.table_widget)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def clicked(self, row, col):
logger.info(f"{row}, {col}")
self.table_widget.selectRow(row)
def populate_cells(self, data):
self.table_widget.setRowCount(len(data))
self.table_widget.setColumnCount(len(data[0]))
for row in range(len(data)):
for col in range(len(data[0])):
value = data[row][col]
self.table_widget.setItem(row, col, QTableWidgetItem(value))
if __name__ == "__main__":
data_sample = [
["customer1", "address1"],
["customer2", "address2"]
]
app = QApplication(sys.argv)
window = TableWindow(data_sample)
window.show()
sys.exit(app.exec())

Reverting imported dictionary via QPushButton issues

I am having trouble understanding why a deep copy of a dictionary reverts back to original values when I run the revert() method once, but when I change values again, and run the revert() method again it changes the copied dictionaries values along with the original.
The dictionary/values are being imported from another file. I can only assume it is because the Test is being imported more than once.
Can someone help explain why this is happening and what can I do to avoid it?
Test.py
import ujson,copy
nested1 = {'1':None, '2':"String"}
nested2 = {'1':0.5123, '2':515}
diction = {'1':nested1, '2':nested2}
copyDiction = ujson.loads(ujson.dumps(diction))
copyOtherDiction = copy.deepcopy(diction)
Main.py
import Test
from PyQt5 import QtCore, QtWidgets, QtGui
class Window(QtWidgets.QMainWindow):
def __init__(self, parent = None):
super(Window,self).__init__(parent)
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
layout = QtWidgets.QVBoxLayout()
self.lineEdit = QtWidgets.QLineEdit()
self.button = QtWidgets.QPushButton("Change Value")
self.button.clicked.connect(self.changeMethod)
self.revertbutton = QtWidgets.QPushButton("Revert")
self.revertbutton.clicked.connect(self.revert)
layout.addWidget(self.lineEdit)
layout.addWidget(self.button)
layout.addWidget(self.revertbutton)
widget.setLayout(layout)
def changeMethod(self):
text = self.lineEdit.text()
if text.isdigit():
Test.diction['1']['2'] = int(text)
else:
Test.diction['1']['2'] = text
def revert(self):
print(Test.diction)
Test.diction = Test.copyDiction
print(Test.diction)
print(Test.copyDiction)
def main():
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

How to connect in realtime two QCombobox

I working on the PyQt5 ui framework. How to connect in realtime two QCombobox so that the QCombobox 2 shall load a data based on the text in QCombobox1.
Here is a very small example. The items in the second combo box are changed by connecting a slot to the textChanged signal of the first combobox. I use a dictionary to look up which items should be displayed in the second combo box depending on the current text in the first combobox.
from PyQt5.QtWidgets import QWidget, QApplication, QComboBox, QFormLayout
class Widget(QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self.categories = {'animals':['cat', 'dog', 'parrot', 'fish'],
'flowers':['daisies', 'tulips', 'daffodils', 'roses'],
'colors':['red', 'orange', 'blue', 'purple']}
self.cat_combobox = QComboBox(self)
self.item_combobox = QComboBox(self)
self.cat_combobox.setEditable(False)
self.item_combobox.setEditable(False)
self.cat_combobox.currentTextChanged.connect(self.set_category)
self.cat_combobox.addItems(sorted(self.categories.keys()))
form_layout = QFormLayout(self)
form_layout.addRow('Category', self.cat_combobox)
form_layout.addRow('Items', self.item_combobox)
def set_category(self, text):
self.item_combobox.clear()
self.item_combobox.addItems(self.categories.get(text, []))
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = Widget()
window.show()
app.exec()

Display a specific item in QcomboBox at start up

I have a QcomboBox with some items in it. When Widget starts up and display first item from QcomboBox. How could QcomboBox be forced to display third item ( Index(2)) in the list by start up?
from PyQt5 import QtWidgets, QtGui
class combo(QtWidgets.QWidget):
def __init__(self, parent = None):
super(combo, self).__init__(parent)
layout = QtWidgets.QHBoxLayout(self)
self.cb = QtWidgets.QComboBox()
self.cb.addItems(["1", "2", "3","4"])
layout.addWidget(self.cb)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = combo()
ex.show()
sys.exit(app.exec_())
The current item can be set with setCurrentIndex().
from PyQt5 import QtWidgets, QtGui
class combo(QtWidgets.QWidget):
def __init__(self, parent = None):
super(combo, self).__init__(parent)
layout = QtWidgets.QHBoxLayout(self)
self.cb = QtWidgets.QComboBox()
self.cb.addItems(["1", "2", "3","4"])
self.cb.setCurrentIndex(2) # <---
layout.addWidget(self.cb)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = combo()
ex.show()
sys.exit(app.exec_())

populating combo box with folders on disk using QFileSystemModel

Hi I have written this basic code trying to populate folders underneath the /Users/ directory, but I don't know what I am missing its not populating.
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
class MyWindow(QtGui.QWidget):
"""docstring for MyWindow"""
def __init__(self, parent=None):
super(MyWindow, self).__init__()
self.setup()
def setup(self):
fsm = QtGui.QFileSystemModel()
fsm.setRootPath("/Users/")
layout = QtGui.QVBoxLayout()
combo = QtGui.QComboBox()
combo.setModel(fsm)
layout.addWidget(combo)
self.setLayout(layout)
def main():
app = QtGui.QApplication(sys.argv)
win = MyWindow()
win.show()
win.raise_()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
I am getting a / in the comobobox instead of the whole list of folders under /Users/ directory.
I think its better to use QFileSystemModel instead of using os.listdir interms of efficiency and will update the view if somebody updates folder or adds folder in the /Users/ directory !
Remember that QFileSystemModel is a hierarchical model, so you need to let the QComboBox know which QModelIndex represents the children you want to display. You do that with QComboBox.setRootModelIndex()
QFileSystemModel.setRootPath() conveniently returns the QModelIndex of the path you set.
So a small change is all you need (tested on Windows) -
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
class MyWindow(QtGui.QWidget):
"""docstring for MyWindow"""
def __init__(self, parent=None):
super(MyWindow, self).__init__()
self.setup()
def setup(self):
fsm = QtGui.QFileSystemModel()
index = fsm.setRootPath("/Users/")
layout = QtGui.QVBoxLayout()
combo = QtGui.QComboBox()
combo.setModel(fsm)
combo.setRootModelIndex(index)
layout.addWidget(combo)
self.setLayout(layout)
def main():
app = QtGui.QApplication(sys.argv)
win = MyWindow()
win.show()
win.raise_()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

Resources