def createLeftSide(self): self.leftSideGB = QGroupBox() home_directory = "./app/" palette = QPalette() palette.setColor(QPalette.Window, QColor(30, 30, 30)) model = QDirModel() view = QTreeView() view.setStyleSheet("QTreeView { border: 0px; }") view.setModel(model) view.setRootIndex(model.index(home_directory)) view.setColumnHidden(1, True) view.setColumnHidden(2, True) view.setColumnHidden(3, True) view.show() view.setPalette(palette) runButton = QPushButton("►") stopButton = QPushButton("❚❚") bottomBar = QHBoxLayout() bottomBar.addWidget(runButton) bottomBar.addWidget(stopButton) layout = QVBoxLayout() layout.addWidget(view) layout.addLayout(bottomBar) layout.setStretch(0, 2) self.leftSideGB.setLayout(layout)
class TreeView(QWidget): def __init__(self, path=None): super(TreeView, self).__init__() self.model = QFileSystemModel() if path: self.selectedPath = path self.model.setRootPath(self.selectedPath) else: self.selectedPath = QDir.currentPath() self.model.setRootPath(self.selectedPath) mainLayout = QVBoxLayout() mainLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(mainLayout) self.tree = QTreeView() self.tree.setModel(self.model) self.tree.setRootIndex(self.model.index(self.selectedPath)) self.tree.setColumnHidden(1, True) self.tree.setColumnHidden(2, True) self.tree.setColumnHidden(3, True) mainLayout.addWidget(self.tree) def changePath(self, path): self.selectedPath = path self.tree.setModel(None) self.model.setRootPath(self.selectedPath) self.model.setNameFilters( ["*.png", "*.jpg", "*.bmp", "*.svg", "*.tiff", "*.gif"]) self.tree.setModel(self.model) self.tree.setRootIndex(self.model.index(self.selectedPath)) self.tree.setColumnHidden(1, True) self.tree.setColumnHidden(2, True) self.tree.setColumnHidden(3, True) self.repaint()
class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) #QWidget.__init__(self) self.createActions() self.createMenus() self.setWindowTitle("Map") self.painter = MyPainter() self.createLayout() self.fileName = '' #按钮 选取状态 self.state = False #QObject.connect(self.painter, QtCore.SIGNAL("get_point_id()"), self, QtCore.SLOT("stateDisplay()")) self.painter.valueChanged.connect(self.stateDisplay) self.button3.clicked.connect(self.clearPoint) self.button0.clicked.connect(self.displayPoint) self.button4.clicked.connect(self.createLane) self.button5.clicked.connect(self.createConn) #读取点号 def stateDisplay(self): self.brower1.setText(str(self.painter.start_point.id)) self.brower2.setText(str(self.painter.end_point.id)) def clearPoint(self): self.painter.target_point = 0 self.painter.start_point.id = '' self.painter.end_point.id = '' self.painter.repaint() self.brower1.setText(str(self.painter.start_point.id)) self.brower2.setText(str(self.painter.end_point.id)) #根据输入框内id显示点号。当不显示时,需点击鼠标两下,由self.target_point的设计决定 def displayPoint(self): self.painter.start_point.id = int(self.brower1.text()) self.painter.start_point.draw_point = self.painter.allPoint[ self.painter.start_point.id].draw_point self.painter.end_point.id = int(self.brower2.text()) self.painter.end_point.draw_point = self.painter.allPoint[ self.painter.end_point.id].draw_point self.painter.repaint() #可能需要加入条件,起始点id小于终止点id。conn同 def createLane(self): #self.painter.data msgBox = QtWidgets.QMessageBox() if (self.painter.start_point.id == '' or self.painter.end_point.id == ''): msgBox.setText("输入错误") else: startline = self.painter.data[self.painter.data[0] == self.painter.start_point.id] endline = self.painter.data[self.painter.data[0] == self.painter.end_point.id] start_index = startline.index.values[0] end_index = endline.index.values[0] output_data = self.painter.data.iloc[start_index:end_index + 1, :] #输出 output_data[0] = output_data[0].astype('int64') num = len(os.listdir("outputDATA\\Lane")) output_data.to_csv('outputDATA\\Lane\\' + str(num) + '.txt', sep='\t', index=False, header=False) #此处不加等于即路段留有衔接点 #存有部分点没删除?for in和remove的问题。 #12.12 保留路段末尾处衔接点,用于生成道路 for item in self.painter.allPoint: if int(item.id) >= int(self.painter.start_point.id) and int( item.id) < int(self.painter.end_point.id): self.painter.displayPoint.remove(item) #print(item.id,self.painter.start_point.id,self.painter.end_point.id) self.painter.repaint() msgBox.setText("已生成目标道路Lane" + str(num)) msgBox.exec_() def createConn(self): #self.painter.data msgBox = QtWidgets.QMessageBox() if (self.painter.start_point.id == '' or self.painter.end_point.id == ''): msgBox.setText("输入错误") else: startline = self.painter.data[self.painter.data[0] == self.painter.start_point.id] endline = self.painter.data[self.painter.data[0] == self.painter.end_point.id] start_index = startline.index.values[0] end_index = endline.index.values[0] output_data = self.painter.data.iloc[start_index:end_index + 1, :] #输出 output_data[0] = output_data[0].astype('int64') num = len(os.listdir("outputDATA\\Conn")) output_data.to_csv('outputDATA\\Conn\\' + str(num) + '.txt', sep='\t', index=False, header=False) for item in self.painter.allPoint: if int(item.id) >= int(self.painter.start_point.id) and int( item.id) < int(self.painter.end_point.id): self.painter.displayPoint.remove(item) #print(item.id,self.painter.start_point.id,self.painter.end_point.id) self.painter.repaint() msgBox.setText("已生成目标道路Conn" + str(num)) msgBox.exec_() def fileList(self): #树状文件列表 self.model = QDirModel() self.view = QTreeView(self) self.view.setModel(self.model) self.view.setColumnHidden(1, True) self.view.setColumnHidden(2, True) self.view.setColumnHidden(3, True) self.view.setHeaderHidden(True) #self.view.setRootIndex(self.model.index("c:/")) self.layout.addWidget(self.view, 0, 0, 2, 1) def createLayout(self): self.widget = QWidget() self.setCentralWidget(self.widget) #栅格布局 self.layout = QGridLayout() #设置拉伸因子,每一列的比例 self.layout.setColumnStretch(0, 1) self.layout.setColumnStretch(1, 4) #控件 self.fileList() self.layout.addWidget(self.painter, 0, 1) #页面 self.button1 = QtWidgets.QLabel("起始点") self.brower1 = QtWidgets.QLineEdit() self.button2 = QtWidgets.QLabel("终止点") self.brower2 = QtWidgets.QLineEdit() self.button3 = QtWidgets.QPushButton("清除") self.button0 = QtWidgets.QPushButton("显示点号") self.button4 = QtWidgets.QPushButton("生成Lane") self.button5 = QtWidgets.QPushButton("生成Conn") labelLayout1 = QtWidgets.QHBoxLayout() labelLayout2 = QtWidgets.QHBoxLayout() labelLayout1.addWidget(self.button1) labelLayout1.addWidget(self.brower1) labelLayout1.addWidget(self.button2) labelLayout1.addWidget(self.brower2) labelLayout1.addWidget(self.button3) labelLayout2.addWidget(self.button0) labelLayout2.addWidget(self.button4) labelLayout2.addWidget(self.button5) self.layout.addLayout(labelLayout1, 1, 1) self.layout.addLayout(labelLayout2, 2, 1) self.widget.setLayout(self.layout) def createActions(self): self.openRoadAct = QtWidgets.QAction("加载道路数据", self, shortcut="Ctrl+O", triggered=self.openRoad) self.openPointAct = QtWidgets.QAction("加载点数据", self, shortcut="Ctrl+P", triggered=self.openPoint) #self.saveAsAct = QtWidgets.QAction("&Save As...", self, shortcut="Ctrl+S",triggered=self.saveAs) self.exitAct = QtWidgets.QAction("退出", self, shortcut="Ctrl+Q", triggered=self.close) #self.aboutAct = QtWidgets.QAction("&About", self, triggered=self.about) #self.aboutQtAct = QtWidgets.QAction("About &Qt", self,triggered=QtWidgets.qApp.aboutQt) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&打开") self.fileMenu.addAction(self.openRoadAct) self.fileMenu.addAction(self.openPointAct) #self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.exitAct) self.menuBar().addSeparator() #self.helpMenu = self.menuBar().addMenu("&Help") #self.helpMenu.addAction(self.aboutAct) #self.helpMenu.addAction(self.aboutQtAct) #加载NovAtel文件数据 def openRoad(self): fileName = QtWidgets.QFileDialog.getOpenFileName( self, "加载数据", QtCore.QDir.currentPath(), "Files (*.txt *.csv)")[0] if not fileName: return inFile = QtCore.QFile(fileName) if not inFile.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtWidgets.QMessageBox.warning( self, "Text", "Cannot read file %s:\n%s." % (fileName, inFile.errorString())) return #data = QtCore.QTextStream(inFile) #self.line=data.readAll() inFile.close() self.painter.addData(fileName) #加载MissionPoint文件数据 #getOpenFileNames()函数,可打开多个文件 def openPoint(self): fileName = QtWidgets.QFileDialog.getOpenFileName( self, "加载数据", QtCore.QDir.currentPath(), "Files (*.txt *.csv)")[0] if not fileName: return inFile = QtCore.QFile(fileName) if not inFile.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtWidgets.QMessageBox.warning( self, "Text", "Cannot read file %s:\n%s." % (fileName, inFile.errorString())) return inFile.close() self.painter.addPointData(fileName)
class SearchReplaceDialog(QDialog): """Search & Replace window """ def __init__(self, parent, initial_query=None): """Initialize the search window """ super(SearchReplaceDialog, self).__init__(parent) self.parent = parent self.prefs = parent.prefs self.items_checked = 0 self.search_button = QPushButton('Search') self.search_text = MySearchField(self.search_button) self.search_text.setPlaceholderText("Enter search query here") self.search_button.clicked.connect(self.submit_search) input_layout = QHBoxLayout() input_layout.addWidget(self.search_text) input_layout.addWidget(self.search_button) self.results_tree = QTreeView() self.results_tree.setRootIsDecorated(False) self.results_tree.setAlternatingRowColors(True) self.results_tree.setAllColumnsShowFocus(True) self.results_tree.setSelectionBehavior(QAbstractItemView.SelectRows) self.results_tree.setSelectionMode(QAbstractItemView.SingleSelection) self.results_tree.doubleClicked.connect(self.go_to_object) self.whole_field_checkbox = QCheckBox("Whole Field Only", self) self.advanced_search_checkbox = QCheckBox("Advanced Search", self) self.advanced_search_checkbox.stateChanged.connect( self.advanced_search_checked) self.ignore_geometry_checkbox = QCheckBox("Ignore Geometry", self) self.go_button = QPushButton('Go') self.go_button.clicked.connect(self.go_to_object) checks_layout = QHBoxLayout() checks_layout.addWidget(self.whole_field_checkbox) checks_layout.addWidget(self.advanced_search_checkbox) checks_layout.addWidget(self.ignore_geometry_checkbox) checks_layout.addStretch() checks_layout.addWidget(self.go_button) self.query_label = QLabel("Query:") self.query_label.setEnabled(False) self.query_text = QLineEdit() self.query_text.setEnabled(True) self.query_text.setReadOnly(True) self.query_text.setFrame(False) self.query_text.setStyleSheet("""QLineEdit { background-color: LightGray; color: white; } """) query_layout = QHBoxLayout() query_layout.addWidget(self.query_label) query_layout.addWidget(self.query_text) self.select_label = QLabel("Select:") self.select_all_button = QPushButton("All") self.select_none_button = QPushButton("None") self.select_invert_button = QPushButton("Invert") self.delete_button = QPushButton("Delete Objects") self.select_all_button.clicked.connect(self.select_all_clicked) self.select_none_button.clicked.connect(self.select_none_clicked) self.select_invert_button.clicked.connect(self.select_invert_clicked) self.delete_button.clicked.connect(self.delete_button_clicked) self.delete_button.setEnabled(False) selection_layout = QHBoxLayout() selection_layout.addWidget(self.select_label) selection_layout.addWidget(self.select_all_button) selection_layout.addWidget(self.select_none_button) selection_layout.addWidget(self.select_invert_button) selection_layout.addStretch() selection_layout.addWidget(self.delete_button) self.replace_with_text = QLineEdit() self.replace_with_label = QLabel("Replace With:") self.replace_button = QPushButton("Replace") self.replace_button.clicked.connect(self.replace_button_clicked) self.replace_button.setEnabled(False) replace_layout = QHBoxLayout() replace_layout.addWidget(self.replace_with_label) replace_layout.addWidget(self.replace_with_text) replace_layout.addWidget(self.replace_button) layout = QVBoxLayout() layout.addLayout(input_layout) layout.addLayout(checks_layout) layout.addLayout(query_layout) layout.addWidget(self.results_tree) layout.addLayout(selection_layout) layout.addLayout(replace_layout) self.resize(650, 450) self.setLayout(layout) self.setWindowTitle("IDF+ Search & Replace") self.search_text.setFocus() self.setTabOrder(self.search_text, self.search_button) self.setTabOrder(self.search_button, self.whole_field_checkbox) self.setTabOrder(self.whole_field_checkbox, self.advanced_search_checkbox) self.setTabOrder(self.advanced_search_checkbox, self.select_all_button) self.setTabOrder(self.select_all_button, self.select_none_button) self.setTabOrder(self.select_none_button, self.select_invert_button) self.setTabOrder(self.select_invert_button, self.replace_with_text) self.setTabOrder(self.replace_with_text, self.replace_button) self.setTabOrder(self.replace_button, self.search_text) self.results_tree.setModel(self.create_results_model([])) self.results_tree.setColumnHidden(2, True) if initial_query is not None: self.search_text.setText(initial_query) self.search_button.click() def create_results_model(self, results): def add_result_row(row_model, value, obj_class, uuid): row_model.insertRow(0) row_model.setData(model.index(0, 0), value) row_model.setData(model.index(0, 1), obj_class) row_model.setData(model.index(0, 2), uuid) item_0 = model.itemFromIndex(model.index(0, 0)) item_0.setCheckState(Qt.Unchecked) item_0.setFlags(item_0.flags() | Qt.ItemIsUserCheckable) item_0.setEditable(False) item_1 = model.itemFromIndex(model.index(0, 1)) item_1.setEditable(False) model = QStandardItemModel(0, 3, self) model.setHeaderData(0, Qt.Horizontal, "Value") model.setHeaderData(1, Qt.Horizontal, "Class") model.setHeaderData(2, Qt.Horizontal, "UUID") for hit in results: add_result_row(model, hit['value'], hit['obj_class_display'], hit['uuid']) return model def submit_search(self): """Submits a search based on the current query """ user_query = self.search_text.text() idf = self.parent.idf if not user_query or len(user_query) < 2 or not idf: return [], "" results, my_query = idf.search( user_query, self.whole_field_checkbox.isChecked(), self.advanced_search_checkbox.isChecked(), self.ignore_geometry_checkbox.isChecked()) self.query_text.setText(str(my_query)) self.results_tree.setModel(self.create_results_model(results)) self.results_tree.model().itemChanged.connect(self.item_checked) # self.results_tree.setColumnHidden(2, True) self.results_tree.resizeColumnToContents(0) self.results_tree.resizeColumnToContents(1) self.results_tree.setSortingEnabled(True) def item_checked(self, item): if item.checkState() == Qt.Checked: self.items_checked += 1 else: self.items_checked -= 1 if self.items_checked > 0: self.delete_button.setEnabled(True) self.replace_button.setEnabled(True) else: self.delete_button.setEnabled(False) self.replace_button.setEnabled(False) def select_all_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): model.itemFromIndex(model.index(i, 0)).setCheckState(Qt.Checked) def select_none_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): model.itemFromIndex(model.index(i, 0)).setCheckState(Qt.Unchecked) def select_invert_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): item = model.itemFromIndex(model.index(i, 0)) if item.checkState() == Qt.Checked: new_state = Qt.Unchecked else: new_state = Qt.Checked item.setCheckState(new_state) def delete_button_clicked(self): model = self.results_tree.model() result_count = model.rowCount() if result_count <= 0 or self.items_checked <= 0: return question = "Are you sure you want to perform this deletion?\n" \ "Undo is currently NOT supported for this operation." response = self.confirm_action(question) if response is not True: return for i in range(result_count): item_0 = model.itemFromIndex(model.index(i, 0)) item_2 = model.itemFromIndex(model.index(i, 2)) if item_0.checkState() != Qt.Checked: continue field = self.parent.idf.field_by_uuid(item_2.text()) obj = field._outer obj_class = self.parent.idf.idf_objects(obj.obj_class) try: index = obj_class.index(obj) self.parent.idf.remove_objects(obj.obj_class, index, index + 1) except ValueError: pass # already deleted self.parent.set_dirty(True) self.submit_search() self.parent.load_table_view(self.parent.current_obj_class) QMessageBox.information(self, "Delete Action", "Deletion Complete!") def advanced_search_checked(self): if self.advanced_search_checkbox.isChecked(): self.whole_field_checkbox.setEnabled(False) self.whole_field_checkbox.setChecked(True) self.ignore_geometry_checkbox.setEnabled(False) self.ignore_geometry_checkbox.setChecked(False) else: self.whole_field_checkbox.setEnabled(True) self.whole_field_checkbox.setChecked(False) self.ignore_geometry_checkbox.setEnabled(True) self.ignore_geometry_checkbox.setChecked(False) def replace_button_clicked(self): search_text = self.search_text.text() replace_with_text = self.replace_with_text.text() if not search_text: return model = self.results_tree.model() result_count = model.rowCount() if result_count <= 0 or self.items_checked <= 0: return question = "Are you sure you want to perform this replacement?\n" \ "Undo is currently NOT supported for this operation." response = self.confirm_action(question) if response is not True: return for i in range(result_count): item_0 = model.itemFromIndex(model.index(i, 0)) item_2 = model.itemFromIndex(model.index(i, 2)) if item_0.checkState() != Qt.Checked: continue field = self.parent.idf.field_by_uuid(item_2.text()) if self.whole_field_checkbox.isChecked( ) or self.advanced_search_checkbox.isChecked(): field.value = replace_with_text else: regex = re.compile(re.escape(search_text), re.IGNORECASE) field.value = regex.sub(replace_with_text, field.value) self.parent.set_dirty(True) self.submit_search() self.parent.load_table_view(self.parent.current_obj_class) QMessageBox.information(self, "Replacement", "Replacement Complete!") def confirm_action(self, question): """Confirm user wants to perform action """ flags = QMessageBox.StandardButton.Yes flags |= QMessageBox.StandardButton.No response = QMessageBox.question(self, "Are you sure?", question, flags) if response == QMessageBox.Yes: return True elif QMessageBox.No: return False else: return False def go_to_object(self, index=None): if index is None: selected = self.results_tree.selectedIndexes() if not selected: return index = selected[0] model = self.results_tree.model() item = model.itemFromIndex(model.index(index.row(), 2)) field = self.parent.idf.field_by_uuid(item.text()) self.parent.activateWindow() self.parent.jump_to_field(field)