| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- 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
- 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.show()
- 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.loader = QUiLoader()
- self.actionCopy.triggered.connect(self.action_copy)
- self.actionPast.triggered.connect(self.action_paste)
- self.actionSelect_all.triggered.connect(self.action_select_all)
- self.actionReport_Exceptions.triggered.connect(self.report_exceptions)
- self.actionStop_GUI.triggered.connect(GUI.Stop)
- self.actionExit.triggered.connect(GUI.Exit)
- self.actionReport_Virtual_Timing.triggered.connect(self.add_sub_win)
- self.actionAbout.triggered.connect(self.about)
- self.actionAnalyze.triggered.connect(self.show_analyze_window)
- self.actionElaborate.triggered.connect(self.elaborate_window)
- self.actionReload_Design.triggered.connect(GUI.ReloadDesign)
- self.textEdit.document().contentsChanged.connect(self.textEdit_change_size)
- self.textEdit.document().contentsChange.connect(self.textEdit_change_contents)
- sys.stdout = Stream()
- sys.stdout.newText.connect(self.outputWritten)
- sys.stderr = sys.stdout
- self.GUI = GUI
- self.setWindowTitle(GUI.Title)
-
- self.sub_win = SubWindows(self)
- self.sub_win.sig.connect(self.sub_win.add_windows)
-
- 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
- widget.textCursor().insertText(clipboard.text())
-
- def action_select_all(self):
- # 获得文本光标所在控件
- widget:QTextBrowser = self.focusWidget()
- if type(widget) not in (QTextBrowser, QTextEdit):
- return
- widget.selectAll()
-
-
- def report_exceptions(self):
- pass
-
- 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 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.mdiArea, 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.mdiArea, win_form)
-
-
- def show_message(self):
- 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")
- self.MessageTreeView.expandAll()
-
-
- 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 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 add_sub_win(self):
- print('add sub')
- self.t = self.loader.load("ui/TimingAnalyze.ui")
- self.mdiArea.addSubWindow(self.t)
- self.t.show()
|