Reputation: 63
the below example is my problem which can not figure it out! i appreciate if anyone can help on this problem. i have set of data which in this example i am reading from csv file. in next step i am filling my QTableWidget with the data. The problem is when i change data and close the tab and open it, the data does not refresh. here is my sample code:
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QVBoxLayout
from PyQt5.QtWidgets import QAction, QTabWidget, QTableWidget, QTableWidgetItem
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100, 100, 400, 400)
self.setup_ui()
self.show()
def setup_ui(self):
# toolbar
self.toolbar = self.addToolBar('Tool Bar')
self.test_btn = QAction('Test', self)
self.toolbar.addAction(self.test_btn)
self.test_btn.triggered.connect(self.load_data)
# tab
self.tabs = QTabWidget()
self.tab_test = QWidget()
self.tabs.setTabsClosable(True)
self.tabs.tabCloseRequested.connect(lambda tab_index: self.tabs.removeTab(tab_index))
self.setCentralWidget(self.tabs)
def load_data(self):
# get data
data = []
with open('test_data.csv', 'r') as f:
header = next(f).replace('\n', '').split(',')
for line in f:
data.append(line.replace('\n', '').split(','))
print(data)
# table and button widget
self.layout = QVBoxLayout()
self.tabs.addTab(self.tab_test, 'Test')
self.table = QTableWidget()
self.layout.addWidget(self.table)
self.tab_test.setLayout(self.layout)
# fill headers
self.table.setColumnCount(len(header))
for i, field_name in enumerate(header):
self.table.setHorizontalHeaderItem(i, QTableWidgetItem(field_name))
# fill data
for row, row_data in enumerate(data):
self.table.insertRow(row)
for col, data in enumerate(row_data):
self.table.setItem(row, col, QTableWidgetItem(str(data)))
def main():
app = QApplication([])
ui = MainWindow()
app.exec_()
if __name__ == '__main__':
main()
and this is the sample data for test_data.csv
:
col_1,col_2
1,2
10,20
100,200
before updating data:
but after updating 100 to 1000 and 200 to 2000 in csv file then closing tab and opening it, the data has been updated but the items of table not!
what am i missing?
Upvotes: 0
Views: 405
Reputation: 820
You're assigning a single QWidget
instance at MainWindow.setup_ui
, right here:
def setup_ui(self): # toolbar self.toolbar = self.addToolBar('Tool Bar') self.test_btn = QAction('Test', self) # . # . # tab self.tabs = QTabWidget() # <-- # . # . # . self.setCentralWidget(self.tabs)
This means that you're always adding the same QWidget
over and over to the QTabWidget
. So, when you call MainWindow.load_data
, this function call self.tabs.addTab(tab_test, 'Test')
does nothing, because the widget is already present on the table widget.
What you should do, is to create a new QWidget
inside MainWindow.load_data
, just like this:
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QVBoxLayout
from PyQt5.QtWidgets import QAction, QTabWidget, QTableWidget, QTableWidgetItem
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100, 100, 400, 400)
self.setup_ui()
self.show()
def setup_ui(self):
# toolbar
toolbar = self.addToolBar('Tool Bar')
test_btn = QAction('Test', self)
toolbar.addAction(test_btn)
test_btn.triggered.connect(self.load_data)
# tab
self.tabs = QTabWidget()
self.tabs.setTabsClosable(True)
self.tabs.tabCloseRequested.connect(lambda tab_index: self.tabs.removeTab(tab_index))
self.setCentralWidget(self.tabs)
def load_data(self):
# get data
data = []
with open('test_data.csv', 'r') as f:
header = next(f).replace('\n', '').split(',')
for line in f:
data.append(line.replace('\n', '').split(','))
print(data)
# table and button widget
layout = QVBoxLayout()
tab_test = QWidget() ## MOVED THIS LINE FROM setup_ui
self.tabs.addTab(tab_test, 'Test')
table = QTableWidget()
layout.addWidget(table)
tab_test.setLayout(layout)
# fill headers
table.setColumnCount(len(header))
for i, field_name in enumerate(header):
table.setHorizontalHeaderItem(i, QTableWidgetItem(field_name))
# fill data
for row, row_data in enumerate(data):
table.insertRow(row)
for col, data in enumerate(row_data):
table.setItem(row, col, QTableWidgetItem(str(data)))
def main():
app = QApplication([])
ui = MainWindow()
app.exec_()
if __name__ == '__main__':
main()
Note that I used local variables on setup_ui
and load_data
scopes. As most variables in there are not being used in other MainWindow
methods, it's not needed to store them to self
, unlike self.tabs
. Also, as every tab should be independent of each other, it's not a good thing to overwrite the self.test_tab
variable, unless you do need to store only the last added tab.
Upvotes: 1