我知道QGraphicsScene.items()返回QGraphicsScene上所有项目的列表,可以根据几个Qt.SortOrder对其进行排序。但是,这些都不对我有用,因为我需要按时间顺序对它们进行排序(在创建它们时)。因此,我想知道是否有可能自己创建此类列表并在需要的时间和位置添加这些项目。
最终实现将是与包含事件描述的QTableWidget相关的时间表(QGraphicsView)。因此,我想单击一行直接进入该事件的开始。
from PyQt5.QtOpenGL import * from PyQt5 import QtCore, QtGui from PyQt5.QtGui import* from PyQt5 import QtCore from PyQt5.QtCore import* from PyQt5 import QtWidgets from PyQt5.QtWidgets import* import sys EVENT_RECT_HEIGHT = 20# 20 EVENT_HEIGHT = 30# 30 TIME_LINE_HEIGHT = 0 TIME_FORMAT = "%Y-%m-%d %H:%M:%S" splitter_sizes_checked = [750, 1500, 50] splitter_sizes_partially_checked = [1, 1000, 50] splitter_sizes_unchecked = [0, 1000, 50] EVENT_HEIGHT = 30 class MainTimelineWindow(QMainWindow): def __init__(self): super(MainTimelineWindow, self).__init__() # Main characteristics of the window self.setWindowTitle("Main Timeline Window") self.setGeometry(50, 50, 1000, 700) #Headers self.timeline_headers_list = ["1", "2", "3", "4", "5"] #User Interface self.initUI() self.metadata_table.verticalHeader().setMinimumSectionSize(0) self.metadata_table.verticalHeader().setDefaultSectionSize(EVENT_HEIGHT) # Changes all vertical headers' size and therefore all row's sizes. Initial value = EVENT_HEIGHT # self.metadata_table.horizontalHeader().setDefaultSectionSize(EVENT_HEIGHT + 100) # Initial height = EVENT_HEIGHT self.defaultSize = self.metadata_table.verticalHeader().defaultSectionSize() # Saves initial value of vertical headers' size #Other self.drag = False self.maximo_zoom = False def initUI(self): #Creation of Options Layout self.options_widget = QWidget() #Checkboxes for hiding or displaying columns and the metadata_table self.checkbox_metadata_table = QtWidgets.QCheckBox() self.checkbox_metadata_table.setChecked(True) self.checkbox_metadata_table.setIcon(QIcon(QPixmap("on.png"))) self.checkbox_metadata_table.setTristate(True) self.checkbox_metadata_table.setFixedWidth(50) self.checkbox_0 = QtWidgets.QCheckBox(self.timeline_headers_list[0]) self.checkbox_0.setChecked(True) self.checkbox_1 = QtWidgets.QCheckBox(self.timeline_headers_list[1]) self.checkbox_1.setChecked(True) self.checkbox_2 = QtWidgets.QCheckBox(self.timeline_headers_list[2]) self.checkbox_2.setChecked(True) self.checkbox_3 = QtWidgets.QCheckBox(self.timeline_headers_list[3]) self.checkbox_3.setChecked(True) self.checkbox_4 = QtWidgets.QCheckBox(self.timeline_headers_list[4]) self.checkbox_4.setChecked(True) #Create Layout for checkboxes self.options_layout = QHBoxLayout() self.options_layout.addWidget(self.checkbox_metadata_table) self.options_layout.addWidget(self.checkbox_0) self.options_layout.addWidget(self.checkbox_1) self.options_layout.addWidget(self.checkbox_2) self.options_layout.addWidget(self.checkbox_3) self.options_layout.addWidget(self.checkbox_4) #Adding layout to widget self.options_widget.setLayout(self.options_layout) #Creation of table and timeline splitter self.metadata_table_and_timeline_splitter = QtWidgets.QSplitter() self.metadata_table_and_timeline_splitter.setOrientation(QtCore.Qt.Horizontal) #Creation of metadata table self.create_metadata_table() self.metadata_table_and_timeline_splitter.addWidget(self.metadata_table) #Creation of View and Scene for timeline self.create_view() self.metadata_table_and_timeline_splitter.addWidget(self.view) # Creation of vertical splitter self.vertical_splitter = QtWidgets.QSplitter() self.vertical_splitter.setOrientation(QtCore.Qt.Vertical) self.vertical_splitter.insertWidget(1, self.metadata_table_and_timeline_splitter) self.vertical_splitter.insertWidget(0, self.options_widget) # Choosing the sizes of the upper and lower widgets of the Qsplitter self.sizes_list = [100, 5000] self.vertical_splitter.setSizes(self.sizes_list) self.setCentralWidget(self.vertical_splitter) #Right click button to open context menu self.metadata_table.setContextMenuPolicy(Qt.CustomContextMenu) self.metadata_table.customContextMenuRequested.connect(self.open_context_menu) def open_context_menu(self, position): menu = QMenu() go_to_associated_rectangle = menu.addAction("Go to event") action = menu.exec_(self.metadata_table.mapToGlobal(position)) row = self.metadata_table.rowAt(position.y())# Gives the row of event. Remember that first row has index 0 column = self.metadata_table.columnAt(position.x())# Gives the column of event. Remember that first column has index 0 if action == go_to_associated_rectangle: self.go_to_event(row, column) def go_to_event(self, row, column): print("Go to event number", row) print(self.timeline.items())# Entrega una lista con todos los items que contiene la escena. No se como estan ordenados. print(self.timeline.items()[row])# Devuelve el item correspondiente a la ubicacion row (a la ubicacion de la fila clickeada). # print(self.timeline.items()[row].scenePos().y()) # print(self.timeline.items()[row].scenePos().x()) print(len(self.timeline.items())) #position_of_rectangle = (self.view.mapFromScene(self.timeline.items()[100].scenePos())) position_of_rectangle = (self.timeline.items()[row].scenePos()) self.view.centerOn(position_of_rectangle) def create_metadata_table(self): self.metadata_table = QTableWidget() self.metadata_table.setColumnCount(len(self.timeline_headers_list)) self.metadata_table.setHorizontalHeaderLabels(self.timeline_headers_list) self.metadata_table.setRowCount(100) def create_view(self): self.view = viewFor() self.timeline = QtWidgets.QGraphicsScene() for i in range(self.metadata_table.rowCount()): rect = QGraphicsRectItem(0, 0, 10 * i, EVENT_RECT_HEIGHT) rect.setPos(i + i * 10, i * EVENT_HEIGHT) #self.timeline.addRect(i + i * 10, i * EVENT_HEIGHT, 10 * i, EVENT_RECT_HEIGHT)#(inicio x, inicio y, ancho, alto) self.timeline.addItem(rect) # self.list_of_items.addItem(rect) # print(self.list_of_widgets) self.view.setScene(self.timeline) class viewFor(QGraphicsView): def __init__(self): super(viewFor, self).__init__() self.setTransformationAnchor(self.NoAnchor) app = QApplication([]) foo = MainTimelineWindow() foo.show() sys.exit(app.exec_())
一般实施
我知道QGraphicsScene.items()返回QGraphicsScene上所有项目的列表,可以根据几个Qt.SortOrder对其进行排序。但是,这些都不对我有用,因为我需要对...进行排序...
有明显的解决方法