| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- import os
- import queue
- import re
- import sys
- import threading
- from PySide2.QtWidgets import QApplication, QMainWindow
- from PySide2.QtUiTools import QUiLoader
- from PySide2.QtWidgets import *
- from PySide2.QtCore import *
- from PySide2 import QtCore
- from PySide2.QtGui import *
- from ui.ui_MainWindows import Ui_MainWindow
- from ui.Analyze import AnalyzeWindow
- from sub_windows import SubWindows,LineEditWin,FormWindow,get_sub_win_list,get_sub_win
- from ui.About import AboutWindow
- from ui.Elaborate import Elaborate
- from ui.Read_Timing_Constraint import ReadTimeWindow
- from ui.ReportException import ReportExceptionWindow
- from ui.ReportClocks import ReportClocks
- from ui.ReportVirtualTiming import ReportVirtualTiming
- from ui.Preferences import PreferencesWindows
- from ui.myui import set_font_size, change_font_size, get_font_size
- import GuiType
- class Stream(QObject):
- """Redirects console output to text widget."""
- newText = Signal(str)
- def __init__(self):
- super().__init__()
- self.stdout_bak = sys.stdout
- self.buffer = self.stdout_bak.buffer
- self.close = self.stdout_bak.close
- self.closed = self.stdout_bak.closed
- self.detach = self.stdout_bak.detach
- self.encoding = self.stdout_bak.encoding
- self.errors = self.stdout_bak.errors
- self.fileno = self.stdout_bak.fileno
- self.flush = self.stdout_bak.flush
- self.isatty = self.stdout_bak.isatty
- self.line_buffering = self.stdout_bak.line_buffering
- self.mode = self.stdout_bak.mode
- self.name = self.stdout_bak.name
- self.newlines = self.stdout_bak.newlines
- self.read = self.stdout_bak.read
- self.readable = self.stdout_bak.readable
- self.readline = self.stdout_bak.readline
- self.readlines = self.stdout_bak.readlines
- self.reconfigure = self.stdout_bak.reconfigure
- self.seek = self.stdout_bak.seek
- self.seekable = self.stdout_bak.seekable
- self.tell = self.stdout_bak.tell
- self.truncate = self.stdout_bak.truncate
- self.writable = self.stdout_bak.writable
- self.write_through = self.stdout_bak.write_through
- self.writelines = self.stdout_bak.writelines
-
- def write(self, text:str):
- self.stdout_bak.write(str(text))
- self.stdout_bak.flush()
- if len(text) == 0:
- return
- if text.isspace():
- return
- self.newText.emit(str(text+'\n'))
- class MessageItem(QTreeWidgetItem):
- def __init__(self, parent, msg:GuiType._GuiMessage):
- super().__init__(parent)
- self.setText(0, msg.Text)
- self.msg = msg
- class MessagesWidgetItem(QTreeWidgetItem):
- def __init__(self, parent, messages:GuiType._GuiMessages, level):
- super().__init__(parent)
- summary = messages.GetSummary()
- self.setText(0, level + f"({messages.Size})")
- for id_, size, text in summary:
- sumary_item = QTreeWidgetItem(self)
- sumary_item.setText(0, f"{id_}({size}):{text}")
-
- for msg in messages.GetMsgByID(id_):
- msg:GuiType._GuiMessage
- MessageItem(sumary_item, msg)
-
- class MainWindow(Ui_MainWindow, QMainWindow):
- textEdit_sig = Signal(str)
- sig = Signal(object)
- def __init__(self, GUI) -> None:
- super().__init__()
- self.setupUi(self)
- # 这里显示一下是为了能获取到 mdiArea 的尺寸,给 sub_windows 使用
- self.GUI = GUI
- self.setWindowTitle(GUI.Title)
- self.show()
-
- sys.stdout = Stream()
- sys.stdout.newText.connect(self.outputWritten)
- sys.stderr = sys.stdout
-
- self.btn_shell.setText(GUI.Prompt)
- self.btn_shell.clicked.connect(self.click_btn_sell)
- self.tabWidget.currentChanged.connect(self.table_widget_change)
- self.tableHistory.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
- self.tableHistory.customContextMenuRequested.connect(self.history_right_click_menu)
- self.MessageTreeView.customContextMenuRequested.connect(self.message_right_click_menu)
- self.status_label = QLabel("Ready")
- self.statusbar.addWidget(self.status_label)
- self.stage_label = QLabel(self.GUI._stage)
- self.statusbar.addPermanentWidget(self.stage_label)
-
- # -- MENUE --
- # file
- self.actionStop_GUI.triggered.connect(GUI.Stop)
- self.actionExit.triggered.connect(GUI.Exit)
- # Edit
- self.actionCopy.triggered.connect(self.action_copy)
- self.actionPast.triggered.connect(self.action_paste)
- self.actionSelect_all.triggered.connect(self.action_select_all)
- # View
- self.actionIncr_Font.triggered.connect(lambda: change_font_size(self, 1))
- self.actionDecr_Font.triggered.connect(lambda: change_font_size(self, -1))
- self.actionToolbar.triggered.connect(lambda: self.toolBar.setHidden(not self.actionToolbar.isChecked()))
- self.actionSidebar.triggered.connect(lambda: self.sub_win.side_bar.mdisubwin.setHidden(not self.actionSidebar.isChecked()))
- self.actionConsole.triggered.connect(lambda: self.tabWidget.setHidden(not self.actionConsole.isChecked()))
- self.actionStatusBar.triggered.connect(lambda: self.statusbar.setHidden(not self.actionStatusBar.isChecked()))
- self.actionSave_as_Default.triggered.connect(self.action_save_as_default)
- self.actionPreferences.triggered.connect(self.preferences)
- self.actionShow_Tab_Bar.triggered.connect(self.toggle_tab_bar)
- # Design
- self.actionAnalyze.triggered.connect(self.show_analyze_window)
- self.actionElaborate.triggered.connect(self.elaborate_window)
- self.actionRead_Timing_Constraint.triggered.connect(self.read_timing_constraint)
- self.actionRead_Power_Intent
- self.actionReload_Design.triggered.connect(self.reload_design)
- # Windows
- # 先实例一个 ActionGroup,等到创建动态窗口的时候,才会在 菜单栏-Window 中添加Action
- self.action_win_group = QActionGroup(self)
- # 获取分隔符,方便 菜单栏-Window-Action 插入到分隔符之前
- self.action_win_separator = self.menuWindow.actions()[0]
- action_tabgroup = QActionGroup(self)
- self.actionLog.setActionGroup(action_tabgroup)
- self.actionHistory.setActionGroup(action_tabgroup)
- self.actionMessages.setActionGroup(action_tabgroup)
- self.actionLog.triggered.connect(self.action_tab_widget)
- self.actionHistory.triggered.connect(self.action_tab_widget)
- self.actionMessages.triggered.connect(self.action_tab_widget)
- # Report
- self.actionReport_Exceptions.triggered.connect(self.report_exception)
- self.actionReport_Clocks.triggered.connect(self.report_clocks)
- self.actionReport_Virtual_Timing.triggered.connect(self.report_virtual_timing)
- # About
- self.actionAbout.triggered.connect(self.about)
- self.textEdit.document().contentsChanged.connect(self.textEdit_change_size)
- self.textEdit.document().contentsChange.connect(self.textEdit_change_contents)
-
- self.sub_win = SubWindows(self)
- self.sub_win.sig.connect(self.sub_win.add_windows)
- set_font_size(self, self.GUI.TextFontSize,self.GUI.TextFont,self.GUI.SysFontSize,self.GUI.SysFont)
- def toggle_tab_bar(self, checked):
- if checked:
- self.mdiArea.setViewMode(QMdiArea.TabbedView)
- self.mdiArea.setTabsClosable(True)
- else:
- self.mdiArea.setViewMode(QMdiArea.SubWindowView)
- def action_copy(self):
- # 获得文本光标所在控件
- widget:QTextBrowser = self.focusWidget()
- if type(widget) not in (QTextBrowser, QTextEdit):
- return
- cur:QTextCursor = widget.textCursor()
- self.copy(cur.selectedText())
- def action_paste(self):
- clipboard = QApplication.clipboard()
- # 获得文本光标所在控件
- widget:QTextBrowser = self.focusWidget()
- if type(widget) not in (QTextBrowser, QTextEdit):
- return
- if widget.isReadOnly():
- return
- widget.textCursor().insertText(clipboard.text())
-
- def action_select_all(self):
- # 获得文本光标所在控件
- widget:QTextBrowser = self.focusWidget()
- if not isinstance(widget, (QTextBrowser, QTextEdit, QPlainTextEdit,)):
- return
- widget.selectAll()
-
- def action_save_as_default(self):
- text_font_size, text_font_family, sys_font_size, sys_font_family = get_font_size(self)
- self.GUI.ViewSetDefault(text_font_size, text_font_family,sys_font_size,sys_font_family)
-
- def action_tab_widget(self):
- action_sender = self.sender()
- action = {
- self.actionLog: 0,
- self.actionHistory: 1,
- self.actionMessages: 2,
- }
- index = action.get(action_sender)
- if index != None:
- self.tabWidget.setCurrentIndex(index)
-
- def read_timing_constraint(self):
- ReadTimeWindow(self, os.getcwd())
-
- def table_widget_change(self, index):
- member = {
- 0: None,
- 1: self.show_history,
- 2: self.show_message
- }
- method = member.get(index)
- if method:
- method()
-
- def show_history(self):
- self.tableHistory.clear()
- blank_row = self.tableHistory.height() / self.tableHistory.verticalHeader().height() + 2
- self.tableHistory.setRowCount(blank_row)
- for row_text in self.GUI.GetHistory():
- end_row = self.tableHistory.rowCount()
- self.tableHistory.insertRow(end_row)
- self.tableHistory.setItem(end_row, 0, QTableWidgetItem(row_text))
- self.tableHistory.scrollToBottom()
-
- def show_message(self):
- if self.tabWidget.currentWidget() != self.MessagePage:
- return
- print("show_message")
- for _ in range(self.MessageTreeView.topLevelItemCount()):
- self.MessageTreeView.takeTopLevelItem(0)
- MessagesWidgetItem(self.MessageTreeView, self.GUI.GetErrors(), "Errors")
- MessagesWidgetItem(self.MessageTreeView, self.GUI.GetCriticalWarnings(), "CriticalWarnings")
- MessagesWidgetItem(self.MessageTreeView, self.GUI.GetWarnings(), "Warnings")
- MessagesWidgetItem(self.MessageTreeView, self.GUI.GetInfos(), "Infos")
-
- def copy(self, text):
- clipboard = QApplication.clipboard()
- clipboard.setText(text)
-
- def history_right_click_menu(self):
- itemPos = self.tableHistory.mapFromGlobal(QCursor().pos())
- item = self.tableHistory.itemAt(itemPos)
- if type(item) != QTableWidgetItem:
- return
- pop_menu = QMenu()
- pop_menu.addAction(QAction('Copy', pop_menu))
- pop_menu.triggered.connect(lambda: self.copy(self.tableHistory.currentItem().text()))
- pop_menu.exec_(QCursor.pos())
- def message_right_click_menu(self):
- itemPos = self.MessageTreeView.mapFromGlobal(QCursor().pos())
- item:MessageItem = self.MessageTreeView.itemAt(itemPos)
- if type(item) != MessageItem:
- return
- pop_menu = QMenu()
- pop_menu.addAction(QAction('Crossprobe', pop_menu))
- pop_menu.addAction(QAction('Properties', pop_menu))
- pop_menu.triggered.connect(lambda action: self.message_popmenu_action(action, item))
- pop_menu.exec_(QCursor.pos())
-
- def message_popmenu_action(self, action, item):
- if action.text() == 'Crossprobe':
- win_line_text = item.msg.CrossProbe()
- win = get_sub_win(self.mdiArea, LineEditWin, win_line_text.Title)
- # 如果窗口已经存在,关闭窗口,以便重新更新数据
- if win:
- win.close()
- LineEditWin(self, win_line_text)
- elif action.text() == 'Properties':
- win_form = item.msg.Properties()
- # 如果窗口已经存在,关闭窗口,以便重新更新数据
- win = get_sub_win(self.mdiArea, FormWindow, win_form.Title)
- if win:
- win.close()
- FormWindow(self, win_form)
-
-
- def about(self):
- d = AboutWindow(self, self.GUI.About)
- d.exec_()
-
- def show_analyze_window(self):
- d = AnalyzeWindow(self, self.GUI.Shell_Execute)
- d.exec_()
-
- def elaborate_window(self):
- d = Elaborate(self)
- d.exec_()
-
- def report_exception(self):
- d = ReportExceptionWindow(self)
- d.exec_()
-
- def report_clocks(self):
- d = ReportClocks(self)
- d.exec_()
-
- def report_virtual_timing(self):
- d = ReportVirtualTiming(self)
- d.exec_()
-
- def preferences(self):
- d = PreferencesWindows(self)
- d.exec_()
-
- def outputWritten(self, text):
- cursor = self.LogText.textCursor()
- cursor.movePosition(QTextCursor.End)
- cursor.insertText(text)
- self.LogText.setTextCursor(cursor)
- self.LogText.ensureCursorVisible()
-
- def textEdit_change_size(self):
- height = self.textEdit.document().size().height()
- self.textEdit.setMinimumHeight(height)
-
- def click_btn_sell(self):
- self.textEdit.append('\n')
-
- def textEdit_change_contents(self, from_index, charsRemoved, charsAdded):
- if not charsAdded:
- return
- stdin = self.textEdit.toPlainText()
- if not stdin:
- return
- # 捕获回车键
- if stdin[from_index] != '\n':
- return
- # 回车时,判断字符串代码是否结束
- if self.GUI.Shell_IsCmdFinished(stdin):
- # 删除回车字符
- stdin = stdin[:from_index] + stdin[from_index+1:]
- print(stdin)
- thread = threading.Thread(target=self.GUI.Shell_Execute, args=(stdin,))
- thread.start()
- self.textEdit.setText('')
- self.textEdit_change_size()
-
- def reload_design(self):
- thread = threading.Thread(target=self.GUI.ReloadDesign)
- thread.start()
-
- def busy(self):
- self.status_label.setText("Busy")
- self.setCursor(Qt.WaitCursor)
-
- def ready(self):
- self.status_label.setText("Ready")
- self.setCursor(Qt.ArrowCursor)
-
- def stage(self):
- print(self.GUI._stage)
- self.stage_label.setText(self.GUI._stage)
-
|