Просмотр исходного кода

SideBar 新增 Crossprobe 动态窗口

mrh 3 лет назад
Родитель
Сommit
1ec8d7795d
6 измененных файлов с 278 добавлено и 14 удалено
  1. 13 4
      GuiType.py
  2. 2 4
      main_windows.py
  3. 88 6
      sub_windows.py
  4. 41 0
      ui/LineEdit.ui
  5. 79 0
      ui/lineNumberWidget.py
  6. 55 0
      ui/ui_LineEdit.py

+ 13 - 4
GuiType.py

@@ -70,7 +70,7 @@ class _GuiWinLinedText():
     def __init__(self, title, lined_text, line):
         self.Title = title
         self.LinedText = lined_text
-        self.Line = line
+        self.GotoLine = line
 
 
 class _GuiWinForm():
@@ -98,10 +98,19 @@ class _GuiSideBar():
 
     def GetForms(self, treenames):
         return _GuiFormMulti([["Sheet1", _GuiForm(["Col1", "Col2"], [[treename, "ok"] for treename in treenames])], ["Sheet2", _GuiForm(["Col1", "Col2"], [[treename, "fail"] for treename in treenames])]])
-
-    def CrossProbe(self, treenames, name):
+    
+    def CrossProbe(self, treenames, formname, formrow):
+        assert isinstance(treenames, list)
+        assert isinstance(formname, str) or isinstance(formname, type(None))
+        assert isinstance(formrow, list)
         line = 1000
-        return _GuiWinLinedText(name, ("Text Start\n\n"+'\n'.join([str(x) for x in treenames])+'\n'.join(['generated line '+str(x) for x in range(line*2)])+"\n\nText End").split("\n"), line)
+        return _GuiWinLinedText(str(formrow), ("Text Start\n\n"+'\n'.join(['generated line '+str(x) for x in range(3, line*2)])+'\n'.join([str(x) for x in treenames])+str(formname)+"\n\nText End").split("\n"), line)
+    
+    def Properties(self, treenames, formname, formrow):
+        assert isinstance(treenames, list)
+        assert isinstance(formname, (str, type(None)))
+        assert isinstance(formrow, list)
+        return _GuiWinForm(str(formname)+" Properties", _GuiForm(["Name", "Property"], [[x, "property"] for x in treenames+formrow]))
 
 
 class _GuiMessages():  # to be further defined

+ 2 - 4
main_windows.py

@@ -45,11 +45,8 @@ class Stream(QObject):
         self.writelines = self.stdout_bak.writelines
         
     def write(self, text:str):
-        # self.stdout_bak.write(bytes(text))
         self.stdout_bak.write(str(text))
         self.stdout_bak.flush()
-        # if '\n' not in text:
-        #     text += '\n'
         if len(text) == 0:
             return
         if text.isspace():
@@ -71,7 +68,6 @@ class MainWindow(Ui_MainWindow, QMainWindow):
 
         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
@@ -96,6 +92,8 @@ class MainWindow(Ui_MainWindow, QMainWindow):
         if not charsAdded:
             return
         stdin = self.textEdit.toPlainText()
+        if not stdin:
+            return
         # 捕获回车键
         if stdin[from_index] != '\n':
             return

+ 88 - 6
sub_windows.py

@@ -7,8 +7,11 @@ from PySide2.QtUiTools import QUiLoader
 from ui.ui_TimingAnalyze import Ui_TimingWindow
 from ui.ui_Form import Ui_Form
 from ui.ui_SideBar import Ui_SideBar
+from ui.lineNumberWidget import LineNumberWidget
+from ui.ui_LineEdit import Ui_LineEdit
 import GuiType
 
+
 class MultiFormWin(Ui_Form,QMainWindow):
     def __init__(self, mdiArea) -> None:
         super().__init__()
@@ -51,6 +54,42 @@ class TreeWidgetItem(QTreeWidgetItem):
         super().__init__(parent)    
         self.tree_row = tree_row
 
+class LineEditWin(Ui_LineEdit, QMainWindow):
+    def __init__(self, mdiArea:QMdiArea, instance:GuiType._GuiWinLinedText) -> None:
+        super().__init__()
+        self.setupUi(self)
+        self.setWindowTitle(instance.Title)
+        
+        self.textBrowser.textChanged.connect(self.__line_widget_line_count_changed)
+        self.lineWidget = LineNumberWidget(self.textBrowser)
+        self.horizontalLayout.insertWidget(0,self.lineWidget)
+        self.instance = instance
+        self.set_text(instance)
+
+        self.mdisubwin = mdiArea.addSubWindow(self)
+        self.mdisubwin.setAttribute(Qt.WA_DeleteOnClose)
+        self.mdisubwin.resize(self.width(), mdiArea.height())
+        self.mdisubwin.show()
+
+        self.go_to_line(self.instance.GotoLine)
+        
+    def set_text(self, instance:GuiType._GuiWinLinedText):
+        for text in instance.LinedText:
+            self.textBrowser.append(text)
+    
+    def go_to_line(self, line):
+        if line > self.lineWidget.line_count():
+            line = self.lineWidget.line_count()
+        cur = self.textBrowser.textCursor()
+        position = self.textBrowser.document().findBlockByLineNumber(line-1).position()
+        cur.setPosition(position, QTextCursor.MoveAnchor)
+        self.textBrowser.setTextCursor(cur)
+    
+    def __line_widget_line_count_changed(self):
+            if self.lineWidget:
+                n = int(self.textBrowser.document().lineCount())
+                self.lineWidget.changeLineCount(n)
+                
 class SideBarWin(Ui_SideBar, QMainWindow):
     def __init__(self, ui, instance:GuiType._GuiSideBar) -> None:
         super().__init__()
@@ -68,8 +107,46 @@ class SideBarWin(Ui_SideBar, QMainWindow):
         self.treeWidget.itemExpanded.connect(self.expand_tree)
         self.treeWidget.itemCollapsed.connect(self.collapse_tree)
         self.treeWidget.currentItemChanged.connect(self.item_change)
+        self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
+        self.treeWidget.customContextMenuRequested.connect(self.right_click_menu)
         self.sheets.activated.connect(self.activate_table_sheet)
-    
+        self.tableView.setContextMenuPolicy(Qt.CustomContextMenu)
+        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
+        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.tableView.customContextMenuRequested.connect(self.right_click_menu)
+        
+    def right_click_menu(self, pos):
+        sender = self.sender()
+        pop_menu  = QMenu()
+        pop_menu.addAction(QAction('Crossprobe', pop_menu))
+        pop_menu.addAction(QAction('Properties', pop_menu))
+        pop_menu.triggered.connect(lambda action: self.right_click_menu_action(action, sender))
+        pop_menu.exec_(QCursor.pos())
+        
+    def add_crossprobe_win(self, sender):
+        item = self.treeWidget.currentItem()
+        tree_names = self.get_tree_names(item)
+        if type(sender) is QTreeWidget:
+            formname = None
+            formrow = []
+        elif type(sender) is QTableView:
+            formname = self.sheets.currentText()
+            formrow = []
+            for column in range(self.tableView.model().columnCount()):
+                data = self.tableView.model().index(self.tableView.currentIndex().row(), column).data()
+                formrow.append(data)
+        line_text = self.instance.CrossProbe(tree_names, formname, formrow)
+        self.lineEdit_win = LineEditWin(self.ui.mdiArea, line_text)
+
+    def add_properties_win(self, sender):
+        pass
+        
+    def right_click_menu_action(self, action:QAction, sender):
+        if action.text() == 'Crossprobe':
+            self.add_crossprobe_win(sender)
+        elif action.text() == 'Properties':
+            self.add_properties_win(sender)
+                
     # 侧边栏只有一个,只需要 update 即可
     def init_win_data(self, instance:GuiType._GuiSideBar):
         if self.treeWidget.topLevelItemCount():
@@ -82,8 +159,9 @@ class SideBarWin(Ui_SideBar, QMainWindow):
         self.setWindowTitle(self.instance.Title)
         self.set_tree(self.instance.Tree)
         self.mdisubwin.update()
+        
 
-    # 添加一行树节点,节点包含 n 列数据
+    # 添加一行树节点,节点包含 n 列数据
     def add_tree_row(self, parent, tree_row:GuiType._GuiTreeRow):
         item = TreeWidgetItem(parent, tree_row)
         item.setText(0,tree_row.Name)
@@ -91,16 +169,19 @@ class SideBarWin(Ui_SideBar, QMainWindow):
             item.setText(i+1,tree_row.Row[i])
         return item
     
-    def item_change(self, item:TreeWidgetItem, column):
-        tree_names = [item.text(0)]
-        parent = item.parent()
+    def get_tree_names(self, tree_item:TreeWidgetItem):
+        tree_names = [tree_item.text(0)]
+        parent = tree_item.parent()
         while 1:
             if parent:
                 tree_names.append(parent.text(0))
                 parent = parent.parent()
             else:
                 break
-        self.form_multi_temp = self.instance.GetForms(tree_names[::-1])
+        return tree_names[::-1]
+    
+    def item_change(self, item:TreeWidgetItem, column):
+        self.form_multi_temp = self.instance.GetForms(self.get_tree_names(item))
         self.set_form_multi(self.form_multi_temp)
       
     def collapse_tree(self, item:TreeWidgetItem):
@@ -208,6 +289,7 @@ class SubWindows(QObject):
         elif isinstance(instance, GuiType._GuiSideBar):
             
             self.side_bar.init_win_data(instance)
+            
 
 if __name__ == '__main__':            
     m = GuiType._GuiWinFormMulti('multi', 1)

+ 41 - 0
ui/LineEdit.ui

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LineEdit</class>
+ <widget class="QMainWindow" name="LineEdit">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>460</width>
+    <height>437</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout">
+    <item row="0" column="0">
+     <layout class="QHBoxLayout" name="horizontalLayout" stretch="0">
+      <item>
+       <widget class="QTextBrowser" name="textBrowser"/>
+      </item>
+     </layout>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>460</width>
+     <height>23</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 79 - 0
ui/lineNumberWidget.py

@@ -0,0 +1,79 @@
+from PySide2.QtGui import QFont, QTextCursor
+from PySide2.QtWidgets import QTextBrowser
+from PySide2.QtCore import Qt
+
+
+class LineNumberWidget(QTextBrowser):
+    def __init__(self, widget):
+        super().__init__()
+        self.__initUi(widget)
+
+    def __initUi(self, widget):
+        self.__lineCount = widget.document().lineCount()
+        self.__size = int(widget.font().pointSizeF())
+        self.__styleInit()
+
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+        self.setTextInteractionFlags(Qt.NoTextInteraction)
+
+        self.verticalScrollBar().setEnabled(False)
+
+        widget.verticalScrollBar().valueChanged.connect(self.__changeLineWidgetScrollAsTargetedWidgetScrollChanged)
+
+        self.__initLineCount()
+
+    def __changeLineWidgetScrollAsTargetedWidgetScrollChanged(self, v):
+        self.verticalScrollBar().setValue(v)
+        self.setWidthByStr()
+
+    def __initLineCount(self):
+        for n in range(1, self.__lineCount+1):
+            self.append(str(n))
+
+    def changeLineCount(self, n):
+        max_one = max(self.__lineCount, n)
+        diff = n-self.__lineCount
+        if max_one == self.__lineCount:
+            first_v = self.verticalScrollBar().value()
+            for i in range(self.__lineCount, self.__lineCount + diff, -1):
+                self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
+                self.moveCursor(QTextCursor.StartOfLine, QTextCursor.MoveAnchor)
+                self.moveCursor(QTextCursor.End, QTextCursor.KeepAnchor)
+                self.textCursor().removeSelectedText()
+                self.textCursor().deletePreviousChar()
+            last_v = self.verticalScrollBar().value()
+            if abs(first_v-last_v) != 2:
+                self.verticalScrollBar().setValue(first_v)
+        else:
+            for i in range(self.__lineCount, self.__lineCount + diff, 1):
+                self.append(str(i + 1))
+
+        self.__lineCount = n
+
+    def setValue(self, v):
+        self.verticalScrollBar().setValue(v)
+        
+    def setFontSize(self, s: float):
+        self.__size = int(s)
+        self.__styleInit()
+    
+    def setWidthByStr(self):
+        withd = (len(str(self.__lineCount)) + 2) * self.__size*0.7
+        self.setFixedWidth(withd)
+    
+    def line_count(self):
+        return self.__lineCount
+        
+    def __styleInit(self):
+        self.__style = f'''
+                       QTextBrowser 
+                       {{ 
+                       background: transparent; 
+                       border: none; 
+                       color: #AAA; 
+                       font: {self.__size}pt;
+                       }}
+                       '''
+        
+        self.setStyleSheet(self.__style)
+        self.setWidthByStr()

+ 55 - 0
ui/ui_LineEdit.py

@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'LineEdit.ui'
+##
+## Created by: Qt User Interface Compiler version 5.15.0
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide2.QtCore import (QCoreApplication, QDate, QDateTime, QMetaObject,
+    QObject, QPoint, QRect, QSize, QTime, QUrl, Qt)
+from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
+    QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter,
+    QPixmap, QRadialGradient)
+from PySide2.QtWidgets import *
+
+
+class Ui_LineEdit(object):
+    def setupUi(self, LineEdit):
+        if not LineEdit.objectName():
+            LineEdit.setObjectName(u"LineEdit")
+        LineEdit.resize(460, 437)
+        self.centralwidget = QWidget(LineEdit)
+        self.centralwidget.setObjectName(u"centralwidget")
+        self.gridLayout = QGridLayout(self.centralwidget)
+        self.gridLayout.setObjectName(u"gridLayout")
+        self.horizontalLayout = QHBoxLayout()
+        self.horizontalLayout.setObjectName(u"horizontalLayout")
+        self.textBrowser = QTextBrowser(self.centralwidget)
+        self.textBrowser.setObjectName(u"textBrowser")
+
+        self.horizontalLayout.addWidget(self.textBrowser)
+
+
+        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
+
+        LineEdit.setCentralWidget(self.centralwidget)
+        self.menubar = QMenuBar(LineEdit)
+        self.menubar.setObjectName(u"menubar")
+        self.menubar.setGeometry(QRect(0, 0, 460, 23))
+        LineEdit.setMenuBar(self.menubar)
+        self.statusbar = QStatusBar(LineEdit)
+        self.statusbar.setObjectName(u"statusbar")
+        LineEdit.setStatusBar(self.statusbar)
+
+        self.retranslateUi(LineEdit)
+
+        QMetaObject.connectSlotsByName(LineEdit)
+    # setupUi
+
+    def retranslateUi(self, LineEdit):
+        LineEdit.setWindowTitle(QCoreApplication.translate("LineEdit", u"MainWindow", None))
+    # retranslateUi
+