Drag and drop files to QTableWidget - python

I'm trying to drag and drop files into a table-widget, but the path will not appear when I drop the files. When I test by using print() the path appears, but the path will not appear in the table. I am not sure why this is happening, I would greatly appreciate some help.
Main code:
import os
import shutil
import sys
import pandas as pd
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtWidgets import *
from vituix_converter_UI import (Ui_MainWindow)
def no_file_selected():
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setWindowIcon(QtGui.QIcon("D:/Python Projects/HATS SAMS Conversion/Icon/Vituix_Converter_Icon_R1.ico"))
msg.setText("No File Was Selected!")
msg.setWindowTitle("Warning!")
retval = msg.exec_()
def process_completed():
msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setWindowIcon(QtGui.QIcon("D:/Python Projects/HATS SAMS Conversion/Icon/Vituix_Converter_Icon_R1.ico"))
msg.setText("Files are converted.")
msg.setWindowTitle("Completed!")
retval = msg.exec_()
class MyMainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.setupUi(self)
self.pushButton_hats.clicked.connect(self.hats_conversion)
self.pushButton_sams.clicked.connect(self.sams_conversion)
self.tableWidget.setAcceptDrops(True)
self.tableWidget.viewport().installEventFilter(self)
types = ['text/uri-list']
types.extend(self.tableWidget.mimeTypes())
self.tableWidget.mimeTypes = lambda: types
self.tableWidget.setRowCount(0)
self.tableWidget.dropEvent(self.eventFilter())
def hats_conversion(self):
hats_file = QtWidgets.QFileDialog.getOpenFileName(self, "Select HATS File", "", 'txt (*.txt)')[0]
if hats_file == '':
no_file_selected()
else:
hats_data = pd.read_csv(hats_file, sep="\t", skiprows=3, header=None, on_bad_lines='skip')
txt_name = []
for i in range(1, 148, 2):
txt_name.append(hats_data.loc[0, i])
hats_data = hats_data.drop([0, 1])
hats_data = hats_data.reset_index(drop=True)
# Select folder to save data output
save_folder = QtWidgets.QFileDialog.getExistingDirectory(self, "Select HATS Save Folder")
# iteration variable for lists in following for loop
i = 1
# iterate over all text names, allocate corresponding data, and then save as txt
for j in range(0, len(txt_name)):
test_df_1 = hats_data[0].values.tolist()
test_df_2 = hats_data[i].values.tolist()
test_df_3 = hats_data[i + 1].values.tolist()
export_df = pd.DataFrame(
{'0': test_df_1,
'1': test_df_2,
'2': test_df_3
})
save_file = save_folder + '/' + txt_name[j] + '.txt'
export_df.to_csv(save_file, sep='\t', index=False, na_rep='NaN', header=False)
i = i + 2
process_completed()
def sams_conversion(self):
sams_file = QtWidgets.QFileDialog.getExistingDirectory(self, "Select SAMS Folder")
if sams_file == '':
no_file_selected()
else:
output_folder = QtWidgets.QFileDialog.getExistingDirectory(self, "Select/Create Save Folder")
if output_folder == '':
no_file_selected()
else:
file_names = []
for x in os.listdir(sams_file):
if x.endswith(".txt"):
file_names.append(x)
for i in range(len(file_names)):
newPath = shutil.copy(os.path.join(sams_file, file_names[i]), output_folder)
sams_data = pd.read_csv(newPath, sep="\t", skiprows=5, header=None, on_bad_lines='skip')
sams_data.to_csv(newPath, sep='\t', index=False, na_rep='NaN', header=False)
process_completed()
def eventFilter(self, source, event):
if event.mimeData().hasUrls():
for url in event.mimeData().urls():
self.addFile(url.toLocalFile())
return True
return super().eventFilter(source, event)
def addFile(self, filepath):
row = self.tableWidget.rowCount()
self.tableWidget.insertRow(row)
item = QtWidgets.QTableWidgetItem(filepath)
self.tableWidget.setItem(row, 0, item)
self.tableWidget.resizeColumnToContents(0)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon("D:/Python Projects/HATS SAMS Conversion/Icon/Vituix_Converter_Icon_R1.ico"))
win = MyMainWindow()
win.show()
sys.exit(app.exec_())
UI code:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'vituix converter.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(400, 500)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMinimumSize(QtCore.QSize(400, 500))
MainWindow.setMaximumSize(QtCore.QSize(400, 500))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap("Icon/Vituix_Converter_Icon_R1.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
MainWindow.setWindowIcon(icon)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth())
self.tableWidget.setSizePolicy(sizePolicy)
self.tableWidget.setMinimumSize(QtCore.QSize(0, 350))
self.tableWidget.setDragEnabled(False)
self.tableWidget.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly)
self.tableWidget.setDefaultDropAction(QtCore.Qt.LinkAction)
self.tableWidget.setAlternatingRowColors(True)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.verticalLayout.addWidget(self.tableWidget, 0, QtCore.Qt.AlignVCenter)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.gridLayout.setVerticalSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.pushButton_hats = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_hats.setMinimumSize(QtCore.QSize(0, 55))
font = QtGui.QFont()
font.setPointSize(9)
font.setBold(True)
font.setWeight(75)
self.pushButton_hats.setFont(font)
self.pushButton_hats.setObjectName("pushButton_hats")
self.gridLayout.addWidget(self.pushButton_hats, 0, 0, 1, 1)
self.pushButton_sams = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_sams.setMinimumSize(QtCore.QSize(0, 55))
font = QtGui.QFont()
font.setPointSize(9)
font.setBold(True)
font.setWeight(75)
self.pushButton_sams.setFont(font)
self.pushButton_sams.setObjectName("pushButton_sams")
self.gridLayout.addWidget(self.pushButton_sams, 0, 1, 1, 1, QtCore.Qt.AlignVCenter)
self.verticalLayout.addLayout(self.gridLayout)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Vituix Converter"))
self.pushButton_hats.setText(_translate("MainWindow", "Vituix HATS"))
self.pushButton_sams.setText(_translate("MainWindow", "Vituix SAMS"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

In order to do this using an event-filter, you need to handle the drag-enter, drag-move and drag-drop events, and accept the events when the mime-data contains urls. The following changes to your example should work as expected:
class MyMainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
...
self.tableWidget.setAcceptDrops(True)
self.tableWidget.viewport().installEventFilter(self)
self.tableWidget.setRowCount(0)
self.tableWidget.setColumnCount(1)
def eventFilter(self, source, event):
if (source is self.tableWidget.viewport() and
(event.type() == QtCore.QEvent.DragEnter or
event.type() == QtCore.QEvent.DragMove or
event.type() == QtCore.QEvent.Drop) and
event.mimeData().hasUrls()):
if event.type() == QtCore.QEvent.Drop:
for url in event.mimeData().urls():
if url.isLocalFile():
self.addFile(url.path())
event.accept()
return True
return super().eventFilter(source, event)

The table has no columns: setItemData() will be ignored if no valid row and column are given:
def addFile(self, filepath):
if not self.tableWidget.columnCount():
self.tableWidget.setColumnCount(1)
# ...
Note that you must always check the event type in an event filter before accessing the event functions, otherwise you'll get an error or even a crash:
def eventFilter(self, source, event):
if event.type() == event.Drop and event.mimeData().hasUrls():
for url in event.mimeData().urls():
self.addFile(url.toLocalFile())
return True
return super().eventFilter(source, event)
Also, remove the following line, which is completely wrong:
self.tableWidget.dropEvent(self.eventFilter())

Related

How to access QLineEdit in QDialog?

I created a custom dialog that contains a QLineEdit. When certain criteria matches on the main screen, the dialog opens up and allows the user to enter input. Upon returning the the main screen, that input needs to be grabbed and used.
In QtDesigner, I created I dialog (with the Ok and Cancel buttons already on it) and added a QLineEdit with an object name of lineEdit.
also I'm using three .py file one is main_app which is importing other two files mainwindow file and dialog file (converted from .ui file)
following is the method I'm using to open dialog in my main_app file.
def open_dialog(self):
Dialog = QtWidgets.QDialog()
ui = sub_search.Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
resp = Dialog.exec_()
if resp == QtWidgets.QDialog.Accepted:
print("Accepted!") #this place will be used to do something more once I have
#userinupt from dialog box
till this end code is working fine I'm not sure how to return and use user input
following is the code I'm trying to return input of lineEdit from dialog box
def get_text_from(self):
if self.lineEdit.text() != "" and self.buttonBox.accepted():
swc = self.lineEdit.text()
return swc
elif self.lineEdit.text() == "" and self.buttonBox.accepted():
warning_message(title="Warning!", message="please provide swc clli,thanks!")
else:
pass
following are the complete code where I want to put more filter based on user input
main_app.py
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.QtWidgets import QMessageBox
import pandas as pd
from pyqt_master_data import search, sub_search
pd.set_option('display.max_rows', None, 'display.max_columns', None)
master_data = pd.read_excel('Master_data.xlsx', 'Shares')
class SearchTool(search.Ui_main, QtWidgets.QMainWindow):
def __init__(self):
super(SearchTool, self).__init__()
self.setupUi(self)
self.push()
def master_data_search(self):
if self.lineEdit.text() != "":
day = self.lineEdit.text().strip()
if day.upper() in "TUESDAY":
self.open_dialog()
else:
day_df = master_data[(master_data.Day.str.contains(day,
case=False, na=False))]
model = PandasModel(day_df)
self.tableView.setModel(model)
def push(self):
self.pushButton.clicked.connect(self.master_data_search)
def open_dialog(self):
Dialog = QtWidgets.QDialog()
ui = sub_search.Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
resp = Dialog.exec_()
if resp == QtWidgets.QDialog.Accepted:
print("Accepted!")
sub_search.Ui_Dialog.get_text_from() #do something here
else:
print('rejected')
def warning_message(title="Warning!", message="Please provide input,
thanks!"):
QMessageBox.information(None, title, message)
class PandasModel(QtCore.QAbstractTableModel):
"""
Class to populate a table view with a pandas dataframe
"""
def __init__(self, data, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self._data = data
def rowCount(self, parent=None):
return len(self._data.values)
def columnCount(self, parent=None):
return self._data.columns.size
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return str(self._data.values[index.row()][index.column()])
return None
def headerData(self, col, orientation, role):
if orientation == QtCore.Qt.Horizontal and role ==
QtCore.Qt.DisplayRole:
return self._data.columns[col]
return None
if __name__ == "__main__":
app = QtWidgets.QApplication([])
qt_app = SearchTool()
qt_app.show()
app.exec_()
search.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_main(object):
def setupUi(self, main):
main.setObjectName("main")
main.resize(855, 886)
main.setMouseTracking(True)
main.setTabletTracking(True)
self.centralwidget = QtWidgets.QWidget(main)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setFrameShape(QtWidgets.QFrame.Box)
self.frame.setFrameShadow(QtWidgets.QFrame.Plain)
self.frame.setObjectName("frame")
self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(self.frame)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(self.frame)
self.lineEdit.setClearButtonEnabled(True)
self.lineEdit.setObjectName("lineEdit")
self.verticalLayout.addWidget(self.lineEdit)
self.pushButton = QtWidgets.QPushButton(self.frame)
font = QtGui.QFont()
font.setBold(True)
font.setItalic(True)
font.setWeight(75)
self.pushButton.setFont(font)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
self.verticalLayout_2.addWidget(self.frame)
self.frame_2 = QtWidgets.QFrame(self.centralwidget)
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_2)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.frame_3 = QtWidgets.QFrame(self.frame_2)
self.frame_3.setMouseTracking(True)
self.frame_3.setTabletTracking(True)
self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_3.setObjectName("frame_3")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_3)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.tableView = QtWidgets.QTableView(self.frame_3)
self.tableView.setMouseTracking(True)
self.tableView.setTabletTracking(True)
self.tableView.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.tableView.setFrameShadow(QtWidgets.QFrame.Plain)
self.tableView.setDragEnabled(True)
self.tableView.setDefaultDropAction(QtCore.Qt.CopyAction)
self.tableView.setSortingEnabled(True)
self.tableView.setObjectName("tableView")
self.verticalLayout_4.addWidget(self.tableView)
self.verticalLayout_3.addWidget(self.frame_3)
self.verticalLayout_2.addWidget(self.frame_2)
main.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(main)
self.menubar.setGeometry(QtCore.QRect(0, 0, 855, 26))
self.menubar.setObjectName("menubar")
main.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(main)
self.statusbar.setObjectName("statusbar")
main.setStatusBar(self.statusbar)
self.retranslateUi(main)
QtCore.QMetaObject.connectSlotsByName(main)
def retranslateUi(self, main):
_translate = QtCore.QCoreApplication.translate
main.setWindowTitle(_translate("main", "MainWindow"))
self.label.setText(_translate("main", "DATA"))
self.lineEdit.setPlaceholderText(_translate("main", "day"))
self.pushButton.setText(_translate("main", "SEARCH"))
sub_search.py
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMessageBox
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(478, 170)
Dialog.setMaximumSize(QtCore.QSize(560, 170))
self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.frame = QtWidgets.QFrame(Dialog)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
self.verticalLayout.setObjectName("verticalLayout")
self.label = QtWidgets.QLabel(self.frame)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(self.frame)
self.lineEdit.setObjectName("lineEdit")
self.verticalLayout.addWidget(self.lineEdit)
self.verticalLayout_2.addWidget(self.frame)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setCenterButtons(True)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout_2.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def get_text_from(self):
if self.lineEdit.text() != "" and self.buttonBox.accepted():
swc = self.lineEdit.text()
return swc
elif self.lineEdit.text() == "" and self.buttonBox.accepted():
warning_message(title="Warning!", message="please provide swc clli,thanks!")
else:
pass
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "TextLabel"))
self.buttonBox.accepted.connect(self.get_text_from)
def warning_message(title="Warning!", message="Please provide input,
thanks!"):
QMessageBox.information(None, title, message)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
my Questions are how do capture lineEdit value and use in my main_app file.
I realize I've still got lots to learn so if someone could point in the right direction that would be awesome. I got decent start but I'm not sure how to finish this..
thanks in advance!
You could try something like this:
class SearchTool(search.Ui_main, QtWidgets.QMainWindow):
def __init__(self):
super(SearchTool, self).__init__()
self.setupUi(self)
self.push()
def master_data_search(self):
if self.lineEdit.text() != "":
day = self.lineEdit.text().strip()
if day.upper() in "TUESDAY":
result = self.open_dialog()
if result is not None:
print(f'the search result was {result}')
else:
print('the search was canceled')
else:
print('do something else')
def push(self):
self.pushButton.clicked.connect(self.master_data_search)
def open_dialog(self):
print('open dialog')
Dialog = QtWidgets.QDialog(self)
ui = sub_search.Ui_Dialog()
ui.setupUi(Dialog)
#Dialog.show()
resp = Dialog.exec_()
if resp == QtWidgets.QDialog.Accepted:
print("Accepted!")
# retrieve text from line edit in dialog and return it
return ui.lineEdit.text()
else:
print('rejected')
return None

How to autorefresh pyqt5 table when the data is updated

I want to add one functionality in my application when update is done then data in pyqt5 table should automatically refreshed with the new data in search results. But when I click the buttom, there is nothing happened.
# -*- coding: utf-8 -*-
from PyQt5 import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
import logging
import logging.config
import time
class Ui_Control_system(object):
def setupUi(self, Control_system):
Control_system.setObjectName("Control_system")
Control_system.resize(1004, 722)
Control_system.setFixedSize(1004, 722)
Control_system.setWindowIcon(QIcon('images/icon.png'))
Control_system.setStyleSheet("QMainWindow{border-image:url(images/background.jpg)}")
self.centralwidget = QtWidgets.QWidget(Control_system)
self.centralwidget.setObjectName("centralwidget")
#表格显示
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(130, 170, 752, 245))
self.tableWidget.setRowCount(8)
self.tableWidget.setColumnCount(6)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.horizontalHeader().setVisible(False)
self.tableWidget.horizontalHeader().setCascadingSectionResizes(False)
self.tableWidget.horizontalHeader().setDefaultSectionSize(125)
self.tableWidget.horizontalHeader().setHighlightSections(True)
self.tableWidget.horizontalHeader().setSortIndicatorShown(False)
self.tableWidget.verticalHeader().setVisible(False)
Control_system.setCentralWidget(self.centralwidget)
self.tableWidget.setAutoFillBackground(True)
self.tableWidget.setItem(0,0,QTableWidgetItem("机器编号"))
self.tableWidget.setItem(0,1,QTableWidgetItem("烟雾值"))
self.tableWidget.setItem(0,2,QTableWidgetItem("火焰值"))
self.tableWidget.setItem(0,3, QTableWidgetItem("温度值"))
self.tableWidget.setItem(0,4, QTableWidgetItem("电流值"))
self.tableWidget.setItem(0,5, QTableWidgetItem("电压值"))
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
self.tableWidget.item(0,0).setFont(font)
self.tableWidget.item(0,1).setFont(font)
self.tableWidget.item(0,2).setFont(font)
self.tableWidget.item(0,3).setFont(font)
self.tableWidget.item(0,4).setFont(font)
self.tableWidget.item(0,5).setFont(font)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(360, 70, 300, 50))
self.label.setObjectName("label")
self.label.setAutoFillBackground(True)
self.label.setAlignment(Qt.AlignCenter)
self.label.setStyleSheet("border-image:url(images/title.png)")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(730, 480, 121, 41))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.slotStart)
Control_system.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(Control_system)
self.statusbar.setObjectName("statusbar")
Control_system.setStatusBar(self.statusbar)
self.retranslateUi(Control_system)
QtCore.QMetaObject.connectSlotsByName(Control_system)
def retranslateUi(self, Control_system):
_translate = QtCore.QCoreApplication.translate
Control_system.setWindowTitle(_translate("Control_system", "实时监控系统"))
self.pushButton.setText(_translate("Control_system", "开始运行"))
def slotStart(self):
#开始按钮不可点击,线程开始
self.pushButton.setEnabled(False)
self.update_data_thread = UpdateData()
self.update_data_thread.update_data.connect(self.set_btn)
self.update_data_thread.start()
def set_btn(self):
self.pushButton.setEnabled(True)
class UpdateData(QtCore.QThread):#使用qt自己本身的线程
update_data=QtCore.pyqtSignal()#因为这个信号槽要继承于Qobject,不然会发生没有emit,connect函数的报错,括号里面填写的是发射的数据类型
#print(".............")
def __init__(self):
super().__init__()
def run(self):
cnt = 0
while True:
cnt += 1
self.tableWidget.setItem(2,2,QTableWidgetItem(cnt))
self.update_data.emit() # 发射信号
time.sleep(1)
if __name__ == '__main__':
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
MainWindow = QtWidgets.QMainWindow()
ui = Ui_Control_system()
ui.setupUi(MainWindow) # 将ui实例绘制到窗口实例上​
desktop = QtWidgets.QApplication.desktop()
x = (desktop.width() - MainWindow.width()) // 2
y = (desktop.height() - MainWindow.height()) // 2
MainWindow.move(x,y)
MainWindow.show()
sys.exit(app.exec())#exec_()方法的作用是“进入程序的主循环直到exit()被调
You cannot and should not modify the GUI directly from another thread, in your case QTableWidget and QTableWidgetItem are part of the GUI so the code: self.tableWidget.setItem(2, 2, QTableWidgetItem(cnt)) is incorrect. What should be done is to send the information to the main thread through elements that are thread-safe such as signals, QEvents, etc.
On the other hand PyQt recommends not modifying the class it generates but creating a widget and using the generated class as an interface(1).
Considering the above the solution is:
import sys
import time
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Control_system(object):
def setupUi(self, Control_system):
Control_system.setObjectName("Control_system")
Control_system.resize(1004, 722)
Control_system.setFixedSize(1004, 722)
Control_system.setWindowIcon(QtGui.QIcon("images/icon.png"))
Control_system.setStyleSheet(
"QMainWindow{border-image:url(images/background.jpg)}"
)
self.centralwidget = QtWidgets.QWidget(Control_system)
self.centralwidget.setObjectName("centralwidget")
# 表格显示
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(130, 170, 752, 245))
self.tableWidget.setRowCount(8)
self.tableWidget.setColumnCount(6)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.horizontalHeader().setVisible(False)
self.tableWidget.horizontalHeader().setCascadingSectionResizes(False)
self.tableWidget.horizontalHeader().setDefaultSectionSize(125)
self.tableWidget.horizontalHeader().setHighlightSections(True)
self.tableWidget.horizontalHeader().setSortIndicatorShown(False)
self.tableWidget.verticalHeader().setVisible(False)
Control_system.setCentralWidget(self.centralwidget)
self.tableWidget.setAutoFillBackground(True)
self.tableWidget.setItem(0, 0, QtWidgets.QTableWidgetItem("机器编号"))
self.tableWidget.setItem(0, 1, QtWidgets.QTableWidgetItem("烟雾值"))
self.tableWidget.setItem(0, 2, QtWidgets.QTableWidgetItem("火焰值"))
self.tableWidget.setItem(0, 3, QtWidgets.QTableWidgetItem("温度值"))
self.tableWidget.setItem(0, 4, QtWidgets.QTableWidgetItem("电流值"))
self.tableWidget.setItem(0, 5, QtWidgets.QTableWidgetItem("电压值"))
font = QtGui.QFont()
font.setPointSize(15)
font.setBold(True)
self.tableWidget.item(0, 0).setFont(font)
self.tableWidget.item(0, 1).setFont(font)
self.tableWidget.item(0, 2).setFont(font)
self.tableWidget.item(0, 3).setFont(font)
self.tableWidget.item(0, 4).setFont(font)
self.tableWidget.item(0, 5).setFont(font)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(360, 70, 300, 50))
self.label.setObjectName("label")
self.label.setAutoFillBackground(True)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.label.setStyleSheet("border-image:url(images/title.png)")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(730, 480, 121, 41))
self.pushButton.setObjectName("pushButton")
Control_system.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(Control_system)
self.statusbar.setObjectName("statusbar")
Control_system.setStatusBar(self.statusbar)
self.retranslateUi(Control_system)
QtCore.QMetaObject.connectSlotsByName(Control_system)
def retranslateUi(self, Control_system):
_translate = QtCore.QCoreApplication.translate
Control_system.setWindowTitle(_translate("Control_system", "实时监控系统"))
self.pushButton.setText(_translate("Control_system", "开始运行"))
class Control_system(QtWidgets.QMainWindow, Ui_Control_system):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.slotStart)
#QtCore.pyqtSlot()
def slotStart(self):
self.pushButton.setEnabled(False)
self.update_data_thread = UpdateData(self)
self.update_data_thread.dataChanged.connect(self.onDataChanged)
self.update_data_thread.start()
#QtCore.pyqtSlot(int, int, str)
def onDataChanged(self, row, column, text):
it = self.tableWidget.item(row, column)
if it is None:
it = QtWidgets.QTableWidgetItem()
self.tableWidget.setItem(row, column, it)
it.setText(text)
class UpdateData(QtCore.QThread):
dataChanged = QtCore.pyqtSignal(int, int, str)
def run(self):
cnt = 0
while True:
cnt += 1
self.dataChanged.emit(2, 2, str(cnt))
time.sleep(1)
if __name__ == "__main__":
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication(sys.argv)
w = Control_system()
w.show()
sys.exit(app.exec_())
Update:
class Control_system(QtWidgets.QMainWindow, Ui_Control_system):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.pushButton.clicked.connect(self.slotStart)
self.pushButton_2.clicked.connect(self.slotStop)
#QtCore.pyqtSlot()
def slotStart(self):
# ...
#QtCore.pyqtSlot(int, int, str)
def onDataChanged(self, row, column, text):
it = self.tableWidget.item(row, column)
if it is None:
it = QtWidgets.QTableWidgetItem()
self.tableWidget.setItem(row, column, it)
it.setText(text)
#QtCore.pyqtSlot()
def slotStop(self):
self.update_data_thread.requestInterruption()
self.update_data_thread.quit()
self.update_data_thread.wait()
self.pushButton.setEnabled(True)
class UpdateData(QtCore.QThread):
dataChanged = QtCore.pyqtSignal(int, int, str)
def run(self):
cnt = 0
while not self.isInterruptionRequested(): # <---
cnt += 1
self.dataChanged.emit(2, 2, str(cnt))
time.sleep(1)
(1) Using the Generated Code

How to save Qlistwidget items in database or in txt file

Hello recently I made app which will I show you below. In pyqt5 I want to save qlistwidget items in txt or in database file but I don't know how to do that and also I want to show automatically saved qlistwidget items in qlistwidget when I will run my app. Also I want to delete selected item from qlistwidget in database and also in qlistwidget Please help me how to do that I have no idea where to start from
I have no idea how to do that
# I am using Pyqt5
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QDialog, QInputDialog, QLineEdit
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
self.MW = MainWindow
MainWindow.setObjectName("MainWindow")
MainWindow.resize(288, 267)
MainWindow.setMinimumSize(QtCore.QSize(270, 114))
MainWindow.setMaximumSize(QtCore.QSize(630, 540))
MainWindow.setBaseSize(QtCore.QSize(285, 260))
MainWindow.setLayoutDirection(QtCore.Qt.LeftToRight)
MainWindow.setStyleSheet("QMainWindow{background-color:#6F2232;}")
MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
MainWindow.setDocumentMode(False)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setLayoutDirection(QtCore.Qt.LeftToRight)
self.centralwidget.setStyleSheet("QWidget{background-color:#6F2232;}")
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setContentsMargins(9, 9, -1, -1)
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setContentsMargins(0, -1, -1, -1)
self.gridLayout.setObjectName("gridLayout")
self.listWidget = QtWidgets.QListWidget(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(13)
self.listWidget.setFont(font)
self.listWidget.setFocusPolicy(QtCore.Qt.StrongFocus)
self.listWidget.setAutoFillBackground(False)
self.listWidget.setStyleSheet("QListWidget{Background-color:#282828;\n"
"color:#FFFFFF}")
self.listWidget.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.listWidget.setFrameShadow(QtWidgets.QFrame.Sunken)
self.listWidget.setLineWidth(1)
self.listWidget.setModelColumn(0)
self.listWidget.setObjectName("listWidget")
self.gridLayout.addWidget(self.listWidget, 0, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 288, 21))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.menubar.sizePolicy().hasHeightForWidth())
self.menubar.setSizePolicy(sizePolicy)
self.menubar.setLayoutDirection(QtCore.Qt.LeftToRight)
self.menubar.setStyleSheet("QMenuBar{background-color:#C3083F;\n"
"color:#FFFFFF}")
self.menubar.setDefaultUp(False)
self.menubar.setNativeMenuBar(True)
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
font = QtGui.QFont()
font.setPointSize(9)
font.setBold(True)
font.setWeight(75)
self.menuFile.setFont(font)
self.menuFile.setLayoutDirection(QtCore.Qt.LeftToRight)
self.menuFile.setStyleSheet("background-color:#C3083F;\n"
"color:#FFFFFF;")
self.menuFile.setToolTipsVisible(True)
self.menuFile.setObjectName("menuFile")
MainWindow.setMenuBar(self.menubar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setEnabled(True)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.toolBar.sizePolicy().hasHeightForWidth())
self.toolBar.setSizePolicy(sizePolicy)
self.toolBar.setFocusPolicy(QtCore.Qt.StrongFocus)
self.toolBar.setLayoutDirection(QtCore.Qt.LeftToRight)
self.toolBar.setStyleSheet("QToolBar{background-color:#282828;\n"
"border:#282828;\n"
"padding:2px;}\n")
self.toolBar.setMovable(True)
self.toolBar.setAllowedAreas(QtCore.Qt.AllToolBarAreas)
self.toolBar.setOrientation(QtCore.Qt.Vertical)
self.toolBar.setIconSize(QtCore.QSize(25, 39))
self.toolBar.setFloatable(True)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolBar)
self.actionAdd = QtWidgets.QAction(MainWindow)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(r"C:\Users\User\Desktop\WORK\test\task\plus.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionAdd.setIcon(icon)
self.actionAdd.setShortcutContext(QtCore.Qt.WindowShortcut)
self.actionAdd.setAutoRepeat(True)
self.actionAdd.setVisible(True)
self.actionAdd.setMenuRole(QtWidgets.QAction.TextHeuristicRole)
self.actionAdd.setIconVisibleInMenu(True)
self.actionAdd.setShortcutVisibleInContextMenu(False)
self.actionAdd.setObjectName("actionAdd")
self.actionRemove = QtWidgets.QAction(MainWindow)
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(r"C:\Users\User\Desktop\WORK\test\task\minus.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionRemove.setIcon(icon1)
self.actionRemove.setAutoRepeat(True)
self.actionRemove.setVisible(True)
self.actionRemove.setIconVisibleInMenu(True)
self.actionRemove.setShortcutVisibleInContextMenu(False)
self.actionRemove.setObjectName("actionRemove")
self.actionUp = QtWidgets.QAction(MainWindow)
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(r"C:\Users\User\Desktop\WORK\test\task\up-arrow (1).png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionUp.setIcon(icon2)
self.actionUp.setAutoRepeat(True)
self.actionUp.setVisible(True)
self.actionUp.setIconVisibleInMenu(True)
self.actionUp.setShortcutVisibleInContextMenu(False)
self.actionUp.setObjectName("actionUp")
self.actionDown = QtWidgets.QAction(MainWindow)
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(r"C:\Users\User\Desktop\WORK\test\task\download.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionDown.setIcon(icon3)
self.actionDown.setAutoRepeat(True)
self.actionDown.setVisible(True)
self.actionDown.setIconVisibleInMenu(True)
self.actionDown.setShortcutVisibleInContextMenu(False)
self.actionDown.setObjectName("actionDown")
self.actionSort = QtWidgets.QAction(MainWindow)
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(r"C:\Users\User\Desktop\WORK\test\task\sort (1).png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionSort.setIcon(icon4)
self.actionSort.setAutoRepeat(True)
self.actionSort.setVisible(True)
self.actionSort.setIconVisibleInMenu(True)
self.actionSort.setShortcutVisibleInContextMenu(False)
self.actionSort.setObjectName("actionSort")
self.actionNotepad = QtWidgets.QAction(MainWindow)
icon5 = QtGui.QIcon()
icon5.addPixmap(QtGui.QPixmap(":/task/spiral_bound_booklet_64px.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.actionNotepad.setIcon(icon5)
self.actionNotepad.setObjectName("actionNotepad")
self.menuFile.addAction(self.actionAdd)
self.menuFile.addAction(self.actionRemove)
self.menuFile.addAction(self.actionUp)
self.menuFile.addAction(self.actionDown)
self.menuFile.addAction(self.actionSort)
self.menuFile.addAction(self.actionNotepad)
self.menubar.addAction(self.menuFile.menuAction())
self.toolBar.addAction(self.actionAdd)
self.toolBar.addAction(self.actionRemove)
self.toolBar.addAction(self.actionUp)
self.toolBar.addAction(self.actionDown)
self.toolBar.addAction(self.actionSort)
self.actionAdd.triggered.connect(self.actAdd)
self.actionRemove.triggered.connect(self.actRemove)
self.actionUp.triggered.connect(self.actUp)
self.actionDown.triggered.connect(self.actDown)
self.actionSort.triggered.connect(self.actSort)
#self.actionRemove.triggered.connect(self.actEdit)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.menuFile.setTitle(_translate("MainWindow", "File"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionAdd.setText(_translate("MainWindow", "Add"))
self.actionRemove.setText(_translate("MainWindow", "Remove"))
self.actionUp.setText(_translate("MainWindow", "Up"))
self.actionDown.setText(_translate("MainWindow", "Down"))
self.actionSort.setText(_translate("MainWindow", "Sort"))
self.actionNotepad.setText(_translate("MainWindow", "Notepad"))
#Here when I will trigger this function I want to add item
#qlistwidget and also add what I wrote in database or txt file
#AUTOMATICALLY. I dont know how to do it please help
def actAdd(self):
row = self.listWidget.currentRow()
QInputDialog.setStyleSheet(self.MW,"QInputDialog{background-color:#C3083F;}")
text, ok = QInputDialog.getText(self.MW,"Add","Add Task")
if ok and text is not None:
self.listWidget.insertItem(row,text)
# Here I want to remove qlistwidget item and remove it from database or in
# txt file too
def actRemove(self):
row = self.listWidget.currentRow()
item = self.listWidget.item(row)
if item is None:
return
else:
item = self.listWidget.takeItem(row)
del item
def actUp(self):
row = self.listWidget.currentRow()
if row >=1:
item = self.listWidget.takeItem(row)
self.listWidget.insertItem(row -1, item)
self.listWidget.setCurrentItem(item)
def actDown(self):
row = self.listWidget.currentRow()
if row < self.listWidget.count() -1:
item = self.listWidget.takeItem(row)
self.listWidget.insertItem(row +1, item)
self.listWidget.setCurrentItem(item)
def actSort(self):
self.listWidget.sortItems()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Instead of writing the data to disk every time you add or remove an entry in the list you could instead only write the data when the app exists. This can be achieved by subclassing QMainWindow and overriding closeEvent like in the example below. In this example the data is saved to save_file.txt. To automatically read in the saved data when the window is initiated you could override MyMainWindow.__init__, e.g.
# Ui_MainWindow() as before
class MyMainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.save_file = 'save_file.txt'
self.read_from_file(self.save_file)
def write_to_file(self, file):
try:
list_widget = self.ui.listWidget
entries = '\n'.join(list_widget.item(ii).text() for ii in range(list_widget.count()))
with open(file, 'w') as fout:
fout.write(entries)
except OSError as err:
print(f"file {file} could not be written")
def read_from_file(self, file):
try:
list_widget = self.ui.listWidget
with open(file, 'r') as fin:
entries = [e.strip() for e in fin.readlines()]
list_widget.insertItems(0, entries)
except OSError as err:
with open(file, 'w'):
pass
def closeEvent(self, event):
should_save = QtWidgets.QMessageBox.question(self, "Save data",
"Should the data be saved?",
defaultButton = QtWidgets.QMessageBox.Yes)
if should_save == QtWidgets.QMessageBox.Yes:
self.write_to_file(self.save_file)
return super().closeEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = MyMainWindow()
MainWindow.show()
sys.exit(app.exec_())

Expand item in QTreeView with QFileSystemModel

I need to going to some directory when user click on button.
User enter path in QInputDialog (for example /mnt/data/Music on linux), and program go to this directory, like M-c in Midnight Commander or cd in ranger, but i don't know how i can do this... I already know all the documentation by heart
main.py
import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import QMainWindow, QInputDialog
import exampleQTV
class PyMap(QMainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.search.clicked.connect(self.searchAction)
def searchAction(self):
text, ok = QInputDialog.getText(self, "Go to", "Enter path")
if ok:
path = text.split("/")
for item in path:
if item != "":
print("ITEM:", item)
self.leftView.keyboardSearch(item)
self.leftView.setExpanded(self.leftView.currentIndex(), True)
print("currentIndex():",self.leftView.model.filePath(self.leftView.currentIndex()))
child = self.leftView.currentIndex().child(0,0)
print("child:", self.leftView.model.filePath(child))
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.leftView = exampleQTV.exampleQTV()
self.leftView.setObjectName("leftView")
self.gridLayout.addWidget(self.leftView, 1, 0, 1, 1)
self.search = QtWidgets.QPushButton(self.centralwidget)
self.search.setObjectName("select")
self.gridLayout.addWidget(self.search, 0, 0, 1, 2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.search.setText(_translate("MainWindow", "Search"))
def main():
app = QtWidgets.QApplication(sys.argv)
window = PyMap()
window.show()
app.exec_()
if __name__ == '__main__':
main()
exampleQTV.py
from PyQt5.QtWidgets import QTreeView, QFileSystemModel
from PyQt5.QtCore import QDir
class exampleQTV(QTreeView):
def __init__(self):
QTreeView.__init__(self)
self.model = QFileSystemModel()
self.model.setRootPath(QDir.rootPath())
self.setModel(self.model)
self.eventCalled = False
self.requestForEscape = False
self.setColumnHidden(1, True)
self.setColumnHidden(2, True)
self.setColumnHidden(3, True)
self.expandAll()
If you want an item to be expanded your ancestors must be expanded, in the following code you implement that logic:
import sys
from PyQt5 import QtCore, QtWidgets
def expandPath(index, view):
if not index.isValid():
return
indexes = []
ix = index
while ix.isValid():
indexes.insert(0, ix)
ix = ix.parent()
for ix in indexes:
view.expand(ix)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
model = QtWidgets.QFileSystemModel()
model.setRootPath(QtCore.QDir.rootPath())
view = QtWidgets.QTreeView()
view.setModel(model)
view.setRootIndex(model.index(QtCore.QDir.rootPath()))
doc_directory = QtCore.QStandardPaths.writableLocation(
QtCore.QStandardPaths.DocumentsLocation
)
ix = model.index(doc_directory)
expandPath(ix, view)
view.resize(640, 480)
for i in (1, 2, 3):
view.setColumnHidden(i, True)
view.show()
sys.exit(app.exec_())

Double right-click listener for a QTableWidget

I have a PyQt5 QTableWidget for which I want to detect double-right-click events.
Here is my 'design.py' module:
from PyQt5 import QtCore, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(790, 472)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tbwMain = QtWidgets.QTabWidget(self.centralwidget)
self.tbwMain.setGeometry(QtCore.QRect(0, 0, 801, 451))
self.tbwMain.setObjectName("tbwMain")
self.tabBoxes = QtWidgets.QWidget()
self.tabBoxes.setObjectName("tabBoxes")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.tabBoxes)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 791, 421))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
spacerItem = QtWidgets.QSpacerItem(220, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.horizontalLayout.addItem(spacerItem)
self.tblBoxes = QtWidgets.QTableWidget(self.horizontalLayoutWidget)
self.tblBoxes.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.tblBoxes.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.tblBoxes.setRowCount(1)
self.tblBoxes.setObjectName("tblBoxes")
self.tblBoxes.setColumnCount(3)
item = QtWidgets.QTableWidgetItem()
self.tblBoxes.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tblBoxes.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tblBoxes.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
item.setTextAlignment(QtCore.Qt.AlignCenter)
self.tblBoxes.setItem(0, 0, item)
item = QtWidgets.QTableWidgetItem()
item.setTextAlignment(QtCore.Qt.AlignCenter)
self.tblBoxes.setItem(0, 1, item)
item = QtWidgets.QTableWidgetItem()
item.setTextAlignment(QtCore.Qt.AlignCenter)
self.tblBoxes.setItem(0, 2, item)
self.tblBoxes.horizontalHeader().setStretchLastSection(True)
self.tblBoxes.verticalHeader().setVisible(False)
self.horizontalLayout.addWidget(self.tblBoxes)
spacerItem1 = QtWidgets.QSpacerItem(220, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.horizontalLayout.addItem(spacerItem1)
self.tbwMain.addTab(self.tabBoxes, "")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tbwMain.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
# - - - - -
self.tblBoxes.doubleClicked.connect(self.tblMouseDoubleClick)
def tblMouseDoubleClick(self):
pass #Get event somehow?
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
As well as my 'main.py' module:
from PyQt5 import QtCore, QtGui, QtWidgets
from design import Ui_MainWindow
import shared.components.tables as tbl
from unshared import boxes as bxs
import switch as swb
stop_threads = False
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
load(self)
def mouseDoubleClickEvent(self, QMouseEvent):
if event.type() == QtCore.QEvent.MouseButtonPress:
if event.button() == QtCore.Qt.RightButton:
print('Double right-click!')
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
I've tried setting up the event by using mouseDoubleClickEvent in the main.py module; however, the clicks only register when clicking in areas of the main window outside of the table.
I've also considered using connect (as shown in design.py), but I don't know how to check to see if the right mouse button is being clicked without the mouse event - and I'm not sure if it is possible for me to get the mouse event. I just want to make it so that when the user double-right-clicks on a cell in my table (tblBoxes) I can detect the event.
Is this possible with either of the methods I've proposed? I'm using Qt Designer, so the less invasive the solution the better.
You can use an event-filter to watch for a MouseButtonDblClick event:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
...
self.tblBoxes.viewport().installEventFilter(self)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseButtonDblClick and
event.buttons() == QtCore.Qt.RightButton and
source is self.tblBoxes.viewport()):
item = self.tblBoxes.itemAt(event.pos())
if item is not None:
print('dblclick:', item.row(), item.column())
return super(MainWindow, self).eventFilter(source, event)

Categories

Resources