Как получить ссылку на элемент QTreeView?
Есть виджет QTreeView, состоящий из нескольких родительских и дочерних элементов (несколько уровней).
Не могу понять как вывести (к примеру в print) значение определенного элемента при его выборе в дереве?
ВАЖНО! Требуется получить не текст, не число, а именно ссылку на объект или сам объект, если это возможно, т.к. дочерние элементы (нижнего уровня) будут ссылаться на кортеж, содержащий текст, числа, переменные.
Т.е. будущее представление работы программы - следующее, в списке кликаю на элемент, на других виджетах появляется информация, хранимая в каком-либо кортеже.
mainwindow.py
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QLabel, QApplication
from Modules.mainwidget import MainWidget
from Modules import styles
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent, flags=QtCore.Qt.Window | QtCore.Qt.MSWindowsFixedSizeDialogHint |
QtCore.Qt.FramelessWindowHint)
self.setWindowTitle("Mechs alpha")
self.setFixedSize(1000, 600)
self.settings = QtCore.QSettings("mons", "Mechs")
self.SGM = MainWidget()
self.setCentralWidget(self.SGM)
self.setStyleSheet(styles.window_style)
self.SGM.setStyleSheet(styles.window_style)
menubar = self.menuBar() # главное меню
menubar.setStyleSheet(styles.menu_style)
menubar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
file_menu = menubar.addMenu("File")
settings_menu = menubar.addMenu("Settings")
about_menu = menubar.addMenu("Help")
save_action = QtWidgets.QAction("Save Profile", self)
file_menu.addAction(save_action)
load_action = QtWidgets.QAction("Load Profile", self)
file_menu.addAction(load_action)
file_menu.addSeparator() # разделитель в меню
exit_action = QtWidgets.QAction("Quit", self)
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
about_action = about_menu.addAction("About", self.aboutInfo)
toolbar = QtWidgets.QToolBar()
self.addToolBar(toolbar)
toolbar.setMovable(False)
toolbar.setFloatable(False)
toolbar.setFixedHeight(30)
toolbar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
open_implant = toolbar.addAction("Implant")
open_academy = toolbar.addAction("Academy")
open_research = toolbar.addAction("Research")
open_recruit = toolbar.addAction("Recruit")
do_screenshot = toolbar.addAction("Screenshot", self.take_screenshot)
if self.settings.contains("X") and self.settings.contains("Y"):
self.move(self.settings.value("X"), self.settings.value("Y"))
self.label = QLabel(self)
self.label.setText("Mechs alpha")
self.label.setStyleSheet(styles.label_style)
self.label.setGeometry(330, 1, 650, 20)
quit_button = QtWidgets.QPushButton('X', self)
quit_button.setFixedSize(20, 20)
quit_button.move(980, 0)
quit_button.setFlat(True)
quit_button.clicked.connect(self.close)
minimize_button = QtWidgets.QPushButton('_', self)
minimize_button.setFixedSize(20, 20)
minimize_button.move(960, 0)
minimize_button.setFlat(True)
minimize_button.clicked.connect(self.showMinimized)
self.pressing = False
def take_screenshot(self):
screen = QApplication.primaryScreen()
winid = self.winId()
pixmap = screen.grabWindow(winid, 240, 50, 750, 530)
clipboard = QApplication.clipboard()
clipboard.setPixmap(pixmap)
def closeEvent(self, evt):
g = self.geometry()
self.settings.setValue("X", g.left())
self.settings.setValue("Y", g.top())
result = QtWidgets.QMessageBox.question(self.SGM, "Closing confirmation",
"Do you really want to close window?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No)
if result == QtWidgets.QMessageBox.Yes:
evt.accept()
QtWidgets.QWidget.closeEvent(self.SGM, evt)
else:
evt.ignore()
def mousePressEvent(self, event):
self.oldPos = event.globalPos()
self.pressing = True
def mouseMoveEvent(self, event):
if self.pressing:
delta = QtCore.QPoint(event.globalPos() - self.oldPos)
self.move(self.x() + delta.x(), self.y() + delta.y())
self.oldPos = event.globalPos()
def mouseReleaseEvent(self, event):
self.pressing = False
def aboutInfo(self):
"""Информация о программе"""
QtWidgets.QMessageBox.about(self, "About app",
"<center>\"Mechs\" v0.0.1 alpha<br><br>"
"(c) 2020-2021")
mainwidget.py
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QLabel
from Modules import shiplist, equipmentlist, styles, fitlist, ships_tuples
class MainWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
grid = QtWidgets.QGridLayout()
grid.setSpacing(1)
shiptree = QtWidgets.QVBoxLayout()
frame_shiptree = QtWidgets.QFrame()
frame_shiptree.setFixedSize(200, 250)
frame_shiptree.setLayout(shiptree)
grid.addWidget(frame_shiptree, 2, 1, 6, 1)
shiptreebox = shiplist.ShipTreeView()
ship_tab = QtWidgets.QTabWidget()
ship_tab.addTab(shiptreebox, "Ship")
ship_tab.addTab(fittreebox, "Fit")
shiptree.addWidget(ship_tab)
ship_tab.setCurrentIndex(0)
ship_tab.setStyleSheet(styles.tab_style)
self.setLayout(grid)
start.pyw Модуль старта приложения
from PyQt5 import QtGui, QtWidgets, QtCore
import sys
import time
from Modules.mainwindow import MainWindow
import styles
sys._excepthook = sys.excepthook
def my_exception_hook(exctype, value, traceback):
"""блок отлова исключения при закрытии программы"""
print(exctype, value, traceback)
sys._excepthook(exctype, value, traceback)
sys.exit(1)
sys.excepthook = my_exception_hook
app = QtWidgets.QApplication(sys.argv)
app.processEvents()
window = MainWindow()
window.show()
try:
sys.exit(app.exec_())
except:
print('exiting')
shiplist.py
from PyQt5 import QtGui, QtWidgets
from Modules import styles
from PyQt5.QtWidgets import QPlainTextEdit, QHBoxLayout, QApplication, QWidget
mist_shiplist_name = QtGui.QStandardItem('Mist')
frost_shiplist_name = QtGui.QStandardItem('Frost')
glimmer_shiplist_name = QtGui.QStandardItem('Glimmer')
frigate_list = (mist_shiplist_name, frost_shiplist_name, glimmer_shiplist_name)
class ShipTreeView(QtWidgets.QTreeView):
def __init__(self, parent=None):
QtWidgets.QTreeView.__init__(self, parent)
self.ship_standard_item_model = QtGui.QStandardItemModel()
self.setStyleSheet(styles.scrollbar_style)
self.setAnimated(True)
self.setIndentation(0)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
frigate_class = QtGui.QStandardItem('Frigate')
self.ship_standard_item_model.appendRow([frigate_class])
self.header().hide()
self.setModel(self.ship_standard_item_model)
t1_frigate_class = QtGui.QStandardItem('T1')
frigate_class.appendRow(t1_frigate_class)
for i in range(len(frigate_list)):
stditem = QtGui.QStandardItem(frigate_list[i])
t1_frigate_class.appendRow([stditem])
self.header().hide()
self.setModel(self.ship_standard_item_model)
t2_frigate_class = QtGui.QStandardItem('T2')
frigate_class.appendRow(t2_frigate_class)
self.header().hide()
self.setModel(self.ship_standard_item_model)
t3_frigate_class = QtGui.QStandardItem('T3')
frigate_class.appendRow(t3_frigate_class)
self.header().hide()
self.setModel(self.ship_standard_item_model)
def get_item(self, index):
return self.ship_standard_item_model.itemFromIndex(index)
Сколько я ни пробовал - не могу врубиться в механику получения вообще чего либо при выборе элемента.
Ответы (2 шт):
Элемент можно получить из модели по индексу. А индекс можно получить из сигнала clicked (для удобства добавил метод get_item)
В качестве примера добавил MyTreeView на окно с другим виджетом. Подключил сигнал clicked у дерева и сделал так, чтобы при клике выводился текст из дерева
Попробуйте:
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPlainTextEdit
# from Modules import styles
first_item_name = QtGui.QStandardItem('first_item')
second_item_name = QtGui.QStandardItem('second_item')
first_list = (first_item_name, second_item_name)
second_list = ['11', '22', '33', '44', '55']
class MyTreeView(QtWidgets.QTreeView):
def __init__(self, parent=None):
QtWidgets.QTreeView.__init__(self, parent)
self.standard_item_model = QtGui.QStandardItemModel()
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
first_class = QtGui.QStandardItem('First')
self.standard_item_model.appendRow([first_class])
self.header().hide()
self.setModel(self.standard_item_model)
second_class = QtGui.QStandardItem('Second')
self.standard_item_model.appendRow([second_class])
self.header().hide()
self.setModel(self.standard_item_model)
t1_first_class = QtGui.QStandardItem('T1')
first_class.appendRow(t1_first_class)
for i in range(len(first_list)):
stditem = QtGui.QStandardItem(first_list[i])
t1_first_class.appendRow([stditem])
self.header().hide()
self.setModel(self.standard_item_model)
t2_first_class = QtGui.QStandardItem('T2')
first_class.appendRow(t2_first_class)
self.header().hide()
self.setModel(self.standard_item_model)
t3_first_class = QtGui.QStandardItem('T3')
first_class.appendRow(t3_first_class)
self.header().hide()
self.setModel(self.standard_item_model)
def get_item(self, index):
return self.standard_item_model.itemFromIndex(index)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.my_tree_view = MyTreeView()
self.my_tree_view.clicked.connect(self.on_tree_view_click)
self.text_edit = QPlainTextEdit()
main_layout = QHBoxLayout()
main_layout.addWidget(self.my_tree_view)
main_layout.addWidget(self.text_edit)
self.setLayout(main_layout)
def on_tree_view_click(self, index):
item = self.my_tree_view.get_item(index)
self.text_edit.appendPlainText(item.text())
if __name__ == '__main__':
app = QApplication([])
mw = MainWindow()
mw.show()
app.exec()
Скриншот:
Вам надо научиться создавать минимально-воспроизводимые примеры. В приведенном вами много лишних вещей, которые отвлекают и не хватает некоторого, чтобы запустить ваше приложение.
Я с трудностями запустил ваше приложение. Строки, которые выдавали ошибки, я просто закомментировал.
Я отметил для вас строки, в которые внес изменения, попробуйте.
import sys
# ? import time
# ? import styles
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.Qt import *
#?
class ShipTreeView(QtWidgets.QTreeView):
def __init__(self, parent=None):
QtWidgets.QTreeView.__init__(self, parent)
#+++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
mist_shiplist_name = QtGui.QStandardItem('Mist')
frost_shiplist_name = QtGui.QStandardItem('Frost')
glimmer_shiplist_name = QtGui.QStandardItem('Glimmer')
frigate_list = (mist_shiplist_name, frost_shiplist_name, glimmer_shiplist_name)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.ship_standard_item_model = QtGui.QStandardItemModel()
# self.setStyleSheet(styles.scrollbar_style)
self.setAnimated(True)
self.setIndentation(0)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
frigate_class = QtGui.QStandardItem('Frigate')
self.ship_standard_item_model.appendRow([frigate_class])
self.header().hide()
self.setModel(self.ship_standard_item_model)
t1_frigate_class = QtGui.QStandardItem('T1')
frigate_class.appendRow(t1_frigate_class)
#? frigate_list
for i in range(len(frigate_list)):
stditem = QtGui.QStandardItem(frigate_list[i])
t1_frigate_class.appendRow([stditem])
self.header().hide()
self.setModel(self.ship_standard_item_model)
t2_frigate_class = QtGui.QStandardItem('T2')
frigate_class.appendRow(t2_frigate_class)
self.header().hide()
self.setModel(self.ship_standard_item_model)
t3_frigate_class = QtGui.QStandardItem('T3')
frigate_class.appendRow(t3_frigate_class)
self.header().hide()
self.setModel(self.ship_standard_item_model)
def get_item(self, index):
return self.ship_standard_item_model.itemFromIndex(index)
#? from Modules import shiplist, equipmentlist, styles, fitlist, ships_tuples
#from Modules.mainwidget import MainWidget
class MainWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
grid = QtWidgets.QGridLayout()
grid.setSpacing(1)
shiptree = QtWidgets.QVBoxLayout()
frame_shiptree = QtWidgets.QFrame()
frame_shiptree.setFixedSize(200, 250)
frame_shiptree.setLayout(shiptree)
grid.addWidget(frame_shiptree, 2, 1, 6, 1)
# shiptreebox = shiplist.ShipTreeView()
self.shiptreebox = ShipTreeView() # +++ self.shiptreebox
self.shiptreebox.clicked.connect(self.on_tree_view_click) # +++
ship_tab = QtWidgets.QTabWidget()
ship_tab.addTab(self.shiptreebox, "Ship")
# ??? fittreebox
# ship_tab.addTab(fittreebox, "Fit")
shiptree.addWidget(ship_tab)
ship_tab.setCurrentIndex(0)
# ship_tab.setStyleSheet(styles.tab_style)
self.setLayout(grid)
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def on_tree_view_click(self, index):
item = self.shiptreebox.get_item(index)
#Возвращает указатель на QStandardItem, связанный с данным индексом.
pointerQStandardItem = self.shiptreebox.ship_standard_item_model.itemFromIndex(index)
print(f'Вы кликнули -> {item.text():>8}, --> pointerQStandardItem -> {pointerQStandardItem}')
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#from Modules.mainwindow import MainWindow
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self, parent,
flags=QtCore.Qt.Window |
QtCore.Qt.MSWindowsFixedSizeDialogHint |
QtCore.Qt.FramelessWindowHint)
self.setWindowTitle("Mechs alpha")
self.setFixedSize(1000, 600)
self.settings = QtCore.QSettings("mons", "Mechs")
self.SGM = MainWidget()
self.setCentralWidget(self.SGM)
# self.setStyleSheet(styles.window_style)
# self.SGM.setStyleSheet(styles.window_style)
menubar = self.menuBar() # главное меню
# menubar.setStyleSheet(styles.menu_style)
menubar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
file_menu = menubar.addMenu("File")
settings_menu = menubar.addMenu("Settings")
about_menu = menubar.addMenu("Help")
save_action = QtWidgets.QAction("Save Profile", self)
file_menu.addAction(save_action)
load_action = QtWidgets.QAction("Load Profile", self)
file_menu.addAction(load_action)
file_menu.addSeparator() # разделитель в меню
exit_action = QtWidgets.QAction("Quit", self)
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
about_action = about_menu.addAction("About", self.aboutInfo)
toolbar = QtWidgets.QToolBar()
self.addToolBar(toolbar)
toolbar.setMovable(False)
toolbar.setFloatable(False)
toolbar.setFixedHeight(30)
toolbar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
open_implant = toolbar.addAction("Implant")
open_academy = toolbar.addAction("Academy")
open_research = toolbar.addAction("Research")
open_recruit = toolbar.addAction("Recruit")
do_screenshot = toolbar.addAction("Screenshot", self.take_screenshot)
#?
if self.settings.contains("X") and self.settings.contains("Y"):
self.move(self.settings.value("X"), self.settings.value("Y"))
self.label = QLabel(self)
self.label.setText("Mechs alpha")
# self.label.setStyleSheet(styles.label_style)
self.label.setGeometry(330, 1, 650, 20)
quit_button = QtWidgets.QPushButton('X', self)
quit_button.setFixedSize(20, 20)
quit_button.move(980, 0)
quit_button.setFlat(True)
quit_button.clicked.connect(self.close)
minimize_button = QtWidgets.QPushButton('_', self)
minimize_button.setFixedSize(20, 20)
minimize_button.move(960, 0)
minimize_button.setFlat(True)
minimize_button.clicked.connect(self.showMinimized)
self.pressing = False
def take_screenshot(self):
screen = QApplication.primaryScreen()
winid = self.winId()
pixmap = screen.grabWindow(winid, 240, 50, 750, 530)
clipboard = QApplication.clipboard()
clipboard.setPixmap(pixmap)
def closeEvent(self, evt):
g = self.geometry()
self.settings.setValue("X", g.left())
self.settings.setValue("Y", g.top())
result = QtWidgets.QMessageBox.question(self.SGM, "Closing confirmation",
"Do you really want to close window?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
QtWidgets.QMessageBox.No)
if result == QtWidgets.QMessageBox.Yes:
evt.accept()
QtWidgets.QWidget.closeEvent(self.SGM, evt)
else:
evt.ignore()
def mousePressEvent(self, event):
self.oldPos = event.globalPos()
self.pressing = True
def mouseMoveEvent(self, event):
if self.pressing:
delta = QtCore.QPoint(event.globalPos() - self.oldPos)
self.move(self.x() + delta.x(), self.y() + delta.y())
self.oldPos = event.globalPos()
def mouseReleaseEvent(self, event):
self.pressing = False
def aboutInfo(self):
"""Информация о программе"""
QtWidgets.QMessageBox.about(self, "About app",
"<center>\"Mechs\" v0.0.1 alpha<br><br>"
"(c) 2020-2021")
sys._excepthook = sys.excepthook
def my_exception_hook(exctype, value, traceback):
"""блок отлова исключения при закрытии программы"""
print(exctype, value, traceback)
sys._excepthook(exctype, value, traceback)
sys.exit(1)
sys.excepthook = my_exception_hook
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
# app.processEvents()
window = MainWindow()
window.show()
sys.exit(app.exec_())
#try:
# sys.exit(app.exec_())
#except:
# print('exiting')

