示例#1
0
class ListPartyView(QWidget):
    def __init__(self, controller):
        QWidget.__init__(self)
        self.controller = controller

        self.view_table = QTableWidget(0, 3)

        self.init()
        self.update_list()

    def init(self):
        # LAYOUT
        layout = QHBoxLayout()
        layout.addWidget(self.view_table)
        self.setLayout(layout)
        self.setMinimumWidth(500)

        # VIEW EVENT
        self.view_table.mouseDoubleClickEvent = self.callback_double_click

        # VIEW SELECTION MODE
        self.view_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.view_table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.view_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # self.view_table.setSortingEnabled(True)

        # VIEW COSMETIC
        # > Column format
        for _i, _label in enumerate(['Name', 'Number', 'Creator']):
            self.view_table.setHorizontalHeaderItem(_i, QTableWidgetItem(_label))
        self.view_table.horizontalHeader().setStretchLastSection(True)
        self.header_min_size = 100

        # > Row format
        self.view_table.verticalHeader().setVisible(False)

    def update_list(self):
        parties_model = self.controller.get_parties_from_server()
        self.view_table.setRowCount(len(parties_model))
        for _i, _party_model in enumerate(parties_model):
            for _j, _label in enumerate(_party_model):
                self.view_table.setItem(_i, _j, QTableWidgetItem(str(_label)))

    def resizeEvent(self, event):
        for _i in range(self.view_table.columnCount()):
            if not _i:
                self.view_table.setColumnWidth(_i, self.width() - self.header_min_size * (self.view_table.columnCount() - 1))
            else:
                self.view_table.setColumnWidth(_i, self.header_min_size)

    def get_selected(self):
        _row_selection = self.view_table.selectedItems()
        _party_name = None
        if len(_row_selection):
            _party_name = _row_selection[0].text()
        return _party_name

    def callback_double_click(self, event):
        if self.view_table.selectedItems():
            self.controller.callback_join_party()
示例#2
0
class InvoiceForm(QWidget):
    submitted = Signal(dict)
    
    def __init__(self, parent=None):                                        # + parent=None
        super().__init__(parent)                                            # + parent
        self.setLayout(QFormLayout())
        self.inputs = dict()
        self.inputs['Customer Name'] = QLineEdit()
        self.inputs['Customer Address'] = QPlainTextEdit()
        self.inputs['Invoice Date'] = QDateEdit(date=QDate.currentDate(), calendarPopup=True)
        self.inputs['Days until Due'] = QSpinBox()
        for label, widget in self.inputs.items():
            self.layout().addRow(label, widget)

        self.line_items = QTableWidget(rowCount=10, columnCount=3)
        self.line_items.setHorizontalHeaderLabels(['Job', 'Rate', 'Hours'])
        self.line_items.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.layout().addRow(self.line_items)
        for row in range(self.line_items.rowCount()):
            for col in range(self.line_items.columnCount()):
                if col > 0:
                    w = QSpinBox()
                    self.line_items.setCellWidget(row, col, w)

        submit = QPushButton('Create Invoice', clicked=self.on_submit)
        
# +     vvvvvv                                        vvvvvvvvvvvvv 
        _print = QPushButton('Print Invoice', clicked=self.window().printpreviewDialog)  # + _print, + self.window()
        self.layout().addRow(submit, _print)                                             # + _print

    def on_submit(self):
        data = {'c_name': self.inputs['Customer Name'].text(),
                'c_addr': self.inputs['Customer Address'].toPlainText(),
                'i_date': self.inputs['Invoice Date'].date().toString(),
                'i_due': self.inputs['Invoice Date'].date().addDays(self.inputs['Days until Due'].value()).toString(),
                'i_terms': '{} days'.format(self.inputs['Days until Due'].value()),
                'line_items': list()}

        for row in range(self.line_items.rowCount()):
            if not self.line_items.item(row, 0):
                continue
            job = self.line_items.item(row, 0).text()
            rate = self.line_items.cellWidget(row, 1).value()
            hours = self.line_items.cellWidget(row, 2).value()
            total = rate * hours
            row_data = [job, rate, hours, total]
            if any(row_data):
                data['line_items'].append(row_data)

        data['total_due'] = sum(x[3] for x in data['line_items'])
        self.submitted.emit(data)
        # remove everything else in this function below this point
# +
        return data                                                            # +++
示例#3
0
class MainWindow(QMainWindow):  # Main window
    def __init__(self):
        super().__init__()
        self.setWindowTitle = 'DD烤肉机'
        self.resize(1870, 820)
        self.mainWidget = QWidget()
        self.mainLayout = QGridLayout()  # Grid layout
        self.mainLayout.setSpacing(10)
        self.mainWidget.setLayout(self.mainLayout)
        self.duration = 60000
        self.bitrate = 2000
        self.fps = 60

        self.initProcess = InitProcess()
        self.previewSubtitle = PreviewSubtitle()
        self.dnldWindow = YoutubeDnld()
        self.exportWindow = exportSubtitle()
        self.videoDecoder = VideoDecoder()
        self.exportWindow.exportArgs.connect(self.exportSubtitle)
        self.stack = QStackedWidget()
        self.stack.setFixedWidth(1300)
        self.mainLayout.addWidget(self.stack, 0, 0, 10, 8)
        buttonWidget = QWidget()
        buttonLayout = QHBoxLayout()
        buttonWidget.setLayout(buttonLayout)
        self.playButton = QPushButton('从本地打开')
        self.playButton.clicked.connect(self.open)
        self.playButton.setFixedWidth(400)
        self.playButton.setFixedHeight(75)
        self.dnldButton = QPushButton('Youtube下载器')
        self.dnldButton.clicked.connect(self.popDnld)
        self.dnldButton.setFixedWidth(400)
        self.dnldButton.setFixedHeight(75)
        buttonLayout.addWidget(self.playButton)
        buttonLayout.addWidget(self.dnldButton)
        self.stack.addWidget(buttonWidget)

        self.videoPath = ''
        self.videoWidth = 1920
        self.videoHeight = 1080
        self.globalInterval = 200
        self.setPlayer()
        self.setSubtitle()
        self.setToolBar()
        self.setCentralWidget(self.mainWidget)
        self.playStatus = False
        self.volumeStatus = True
        self.volumeValue = 100
        self.subSelectedTxt = ''
        self.subReplayTime = 1
        self.clipBoard = []
        self.grabKeyboard()
        self.show()

    def setPlayer(self):
        self.playerWidget = QGraphicsVideoItem()
        self.scene = QGraphicsScene()
        self.view = QGraphicsView(self.scene)
        self.view.resize(1280, 730)
        self.scene.addItem(self.playerWidget)
        self.stack.addWidget(self.view)
        self.player = QMediaPlayer(self, QMediaPlayer.VideoSurface)
        self.player.setVideoOutput(self.playerWidget)
        self.view.installEventFilter(self)
        self.view.show()
        self.srtTextItemDict = {0: QGraphicsTextItem(), 1: QGraphicsTextItem(), 2: QGraphicsTextItem(), 3: QGraphicsTextItem(), 4: QGraphicsTextItem()}
        for _, srtTextItem in self.srtTextItemDict.items():
            self.scene.addItem(srtTextItem)

    def setSubtitle(self):
        self.subtitleDict = {x: {-1: [100, '']} for x in range(5)}
        self.subTimer = QTimer()
        self.subTimer.setInterval(100)
        self.subtitle = QTableWidget()
        self.subtitle.setAutoScroll(False)
        self.subtitle.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.mainLayout.addWidget(self.subtitle, 0, 8, 10, 12)
        self.subtitle.setColumnCount(5)
        self.subtitle.selectRow(0)
        self.subtitle.setHorizontalHeaderLabels(['%s' % (i + 1) for i in range(5)])
        self.subtitle.setVerticalHeaderLabels([cnt2Time2(i, self.globalInterval) for i in range(self.subtitle.rowCount())])
        for index in range(5):
            self.subtitle.setColumnWidth(index, 130)
        self.subtitle.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.subtitle.setEditTriggers(QAbstractItemView.DoubleClicked)
        self.subtitle.horizontalHeader().sectionClicked.connect(self.addSubtitle)
        self.subtitle.doubleClicked.connect(self.releaseKeyboard)
        self.subtitle.cellChanged.connect(self.subEdit)
        self.subtitle.verticalHeader().sectionClicked.connect(self.subHeaderClick)
        self.subtitle.setContextMenuPolicy(Qt.CustomContextMenu)
        self.subtitle.customContextMenuRequested.connect(self.popTableMenu)
        self.initSubtitle()

    def initSubtitle(self):
        self.initProcess.show()
        self.subtitle.cellChanged.disconnect(self.subEdit)
        for x in range(self.subtitle.columnCount()):
            for y in range(self.subtitle.rowCount()):
                self.subtitle.setSpan(y, x, 1, 1)
        self.subtitle.setRowCount(self.duration // self.globalInterval + 1)
        for x in range(self.subtitle.columnCount()):
            for y in range(self.subtitle.rowCount()):
                self.subtitle.setItem(y, x, QTableWidgetItem(''))
                self.subtitle.item(y, x).setBackground(QBrush(QColor('#232629')))
        self.subtitle.setVerticalHeaderLabels([cnt2Time2(i, self.globalInterval) for i in range(self.subtitle.rowCount())])
        self.subtitle.cellChanged.connect(self.subEdit)
        self.initProcess.hide()

    def addSubtitle(self, index):
        subtitlePath = QFileDialog.getOpenFileName(self, "请选择字幕", None, "字幕文件 (*.srt *.vtt *.ass *.ssa)")[0]
        if subtitlePath:
            self.initProcess.show()
            self.subtitle.cellChanged.disconnect(self.subEdit)
            if subtitlePath.endswith('.ass') or subtitlePath.endswith('.ssa'):
                p = subprocess.Popen(['utils/ffmpeg.exe', '-y', '-i', subtitlePath, 'temp_sub.srt'])
                p.wait()
                subtitlePath = 'temp_sub.srt'
            subData = {}
            with open(subtitlePath, 'r', encoding='utf-8') as f:
                f = f.readlines()
            subText = ''
            YoutubeAutoSub = False
            for l in f:
                if '<c>' in l:
                    YoutubeAutoSub = True
                    break
            for cnt, l in enumerate(f):
                if '<c>' in l:
                    lineData = l.split('c>')
                    if len(lineData) > 3:
                        subText, start, _ = lineData[0].split('<')
                        start = calSubTime(start[:-1]) // self.globalInterval * self.globalInterval
                        if start not in self.subtitleDict[index]:
                            end = calSubTime(lineData[-3][1:-2]) // self.globalInterval * self.globalInterval
                            for i in range(len(lineData) // 2):
                                subText += lineData[i * 2 + 1][:-2]
                            subData[start] = [end - start, subText]
                    else:
                        subText, start, _ = lineData[0].split('<')
                        start = calSubTime(start[:-1]) // self.globalInterval * self.globalInterval
                        if start not in self.subtitleDict[index]:
                            subText += lineData[1][:-2]
                            subData[start] = [self.globalInterval, subText]
                elif '-->' in l and f[cnt + 2].strip() and '<c>' not in f[cnt + 2]:
                    subText = f[cnt + 2][:-1]
                    start = calSubTime(l[:12]) // self.globalInterval * self.globalInterval
                    if start not in self.subtitleDict[index]:
                        end = calSubTime(l[17:29]) // self.globalInterval * self.globalInterval
                        subData[start] = [end - start, subText]
                if '-->' in l and f[cnt + 1].strip() and not YoutubeAutoSub:
                    start = calSubTime(l[:12]) // self.globalInterval * self.globalInterval
                    if start not in self.subtitleDict[index]:
                        end = calSubTime(l[17:29]) // self.globalInterval * self.globalInterval
                        delta = end - start
                        if delta > 10:
                            if '<b>' in f[cnt + 1]:
                                subData[start] = [delta, f[cnt + 1].split('<b>')[1].split('<')[0]]
                            else:
                                subData[start] = [delta, f[cnt + 1][:-1]]
            self.subtitleDict[index].update(subData)
            maxRow = 0
            for _, v in self.subtitleDict.items():
                startMax = max(v.keys())
                rowCount = (startMax + v[startMax][0]) // self.globalInterval
                if rowCount > maxRow:
                    maxRow = rowCount
            if maxRow < self.duration // self.globalInterval + 1:
                maxRow = self.duration // self.globalInterval
            else:
                self.duration = maxRow * self.globalInterval
            self.subtitle.setRowCount(maxRow)
            self.subtitle.setVerticalHeaderLabels([cnt2Time2(i, self.globalInterval) for i in range(self.subtitle.rowCount())])
            for start, rowData in subData.items():
                startRow = start // self.globalInterval
                endRow = startRow + rowData[0] // self.globalInterval
                for row in range(startRow, endRow):
                    self.subtitle.setItem(row, index, QTableWidgetItem(rowData[1]))
                    self.subtitle.item(row, index).setBackground(QBrush(QColor('#35545d')))
                self.subtitle.setSpan(startRow, index, endRow - startRow, 1)
            self.refreshComboBox()
            self.subtitle.cellChanged.connect(self.subEdit)
            self.initProcess.hide()

    def subTimeOut(self):
        fontColor = self.previewSubtitle.fontColor
        fontSize = (self.previewSubtitle.fontSize + 5) / 2.5
        fontBold = self.previewSubtitle.bold
        fontItalic = self.previewSubtitle.italic
        fontShadowOffset = self.previewSubtitle.shadowOffset
        for _, srtTextItem in self.srtTextItemDict.items():
            srtTextItem.setDefaultTextColor(fontColor)
            font = QFont()
            font.setFamily("微软雅黑")
            font.setPointSize(fontSize)
            font.setBold(fontBold)
            font.setItalic(fontItalic)
            srtTextItem.setFont(font)
            srtTextShadow = QGraphicsDropShadowEffect()
            srtTextShadow.setOffset(fontShadowOffset)
            srtTextItem.setGraphicsEffect(srtTextShadow)
        try:
            selected = self.subtitle.selectionModel().selection().indexes()
            for x, i in enumerate(selected):
                if self.subtitle.item(i.row(), x):
                    txt = self.subtitle.item(i.row(), x).text()
                    if txt:
                        self.srtTextItemDict[x].setPlainText('#%s:' % (x + 1) + txt)
                        txtSize = self.srtTextItemDict[x].boundingRect().size()
                        posY = self.playerWidget.size().height() - txtSize.height() * (x + 1)
                        posX = (self.playerWidget.size().width() - txtSize.width()) / 2
                        self.srtTextItemDict[x].setPos(posX, posY)
                    else:
                        self.srtTextItemDict[x].setPlainText('')
                else:
                    self.srtTextItemDict[x].setPlainText('')
        except:
            pass

    def subHeaderClick(self, index):
        if self.player.duration():
            position = index * self.globalInterval
            self.player.setPosition(position)
            self.videoSlider.setValue(position * 1000 // self.player.duration())
            self.setTimeLabel()

    def subEdit(self, row, index):
        repeat = self.subtitle.rowSpan(row, index)
        self.setSubtitleDict(row, index, repeat, self.subtitle.item(row, index).text())
        self.subtitle.cellChanged.disconnect(self.subEdit)
        for cnt in range(repeat):
            if self.subtitle.item(row + cnt, index).text():
                self.subtitle.item(row, index).setBackground(QBrush(QColor('#35545d')))
            else:
                self.subtitle.item(row, index).setBackground(QBrush(QColor('#232629')))
        self.subtitle.cellChanged.connect(self.subEdit)

    def setSubtitleDict(self, row, index, num, text):
        self.subtitleDict[index][row * self.globalInterval] = [num * self.globalInterval, text]

    def popTableMenu(self, pos):
        self.subtitle.cellChanged.disconnect(self.subEdit)
        pos = QPoint(pos.x() + 55, pos.y() + 30)
        menu = QMenu()
        copy = menu.addAction('复制')
        paste = menu.addAction('粘贴')
        setSpan = menu.addAction('合并')
        clrSpan = menu.addAction('拆分')
        addSub = menu.addAction('导入字幕')
        cutSub = menu.addAction('裁剪字幕')
        action = menu.exec_(self.subtitle.mapToGlobal(pos))
        selected = self.subtitle.selectionModel().selection().indexes()
        yList = [selected[0].row(), selected[-1].row()]
        xSet = set()
        for i in range(len(selected)):
            xSet.add(selected[i].column())
        if action == copy:
            for x in xSet:
                self.clipBoard = []
                for y in range(yList[0], yList[1] + 1):
                    if self.subtitle.item(y, x):
                        self.clipBoard.append(self.subtitle.item(y, x).text())
                    else:
                        self.clipBoard.append('')
                break
        elif action == paste:
            self.subtitle.cellChanged.connect(self.subEdit)
            for x in xSet:
                for cnt, text in enumerate(self.clipBoard):
                    self.subtitle.setItem(yList[0] + cnt, x, QTableWidgetItem(text))
                    self.subtitleDict[x][(yList[0] + cnt) * self.globalInterval] = [self.globalInterval, text]
            self.subtitle.cellChanged.disconnect(self.subEdit)
        elif action == setSpan:
            for x in xSet:
                if not self.subtitle.item(yList[0], x):
                    firstItem = ''
                else:
                    firstItem = self.subtitle.item(yList[0], x).text()
                for y in range(yList[0], yList[1] + 1):
                    self.subtitle.setSpan(y, x, 1, 1)
                    self.subtitle.setItem(y, x, QTableWidgetItem(firstItem))
                    self.subtitle.item(y, x).setBackground(QBrush(QColor('#35545d')))
                    if y * self.globalInterval in self.subtitleDict[x]:
                        del self.subtitleDict[x][y * self.globalInterval]
            for x in xSet:
                self.subtitle.setSpan(yList[0], x, yList[1] - yList[0] + 1, 1)
            self.setSubtitleDict(yList[0], x, yList[1] - yList[0] + 1, firstItem)
        elif action == clrSpan:
            for x in xSet:
                if not self.subtitle.item(yList[0], x):
                    firstItem = ''
                else:
                    firstItem = self.subtitle.item(yList[0], x).text()
                for cnt, y in enumerate(range(yList[0], yList[1] + 1)):
                    self.subtitle.setSpan(y, x, 1, 1)
                    if not cnt:
                        self.subtitle.setItem(yList[0], x, QTableWidgetItem(firstItem))
                        if firstItem:
                            self.subtitle.item(y, x).setBackground(QBrush(QColor('#35545d')))
                        else:
                            self.subtitle.item(y, x).setBackground(QBrush(QColor('#232629')))
                    else:
                        self.subtitle.setItem(y, x, QTableWidgetItem(''))
                        self.subtitle.item(y, x).setBackground(QBrush(QColor('#232629')))
                    self.setSubtitleDict(yList[0], x, yList[1] - yList[0] + 1, firstItem)
                break
        elif action == addSub:
            self.subtitle.cellChanged.connect(self.subEdit)
            for x in xSet:
                self.addSubtitle(x)
            self.subtitle.cellChanged.disconnect(self.subEdit)
        elif action == cutSub:
            for x in xSet:
                start = yList[0] * self.globalInterval
                end = yList[1] * self.globalInterval
                self.exportSubWindow(start, end, x + 1)
        self.subtitle.cellChanged.connect(self.subEdit)

    def setToolBar(self):
        '''
        menu bar, file menu, play menu, tool bar.
        '''
        toolBar = QToolBar()
        self.setContextMenuPolicy(Qt.NoContextMenu)
        self.addToolBar(toolBar)
        fileMenu = self.menuBar().addMenu('&文件')
        openAction = QAction(QIcon.fromTheme('document-open'), '&打开...', self, shortcut=QKeySequence.Open, triggered=self.open)
        fileMenu.addAction(openAction)
        downloadAction = QAction(QIcon.fromTheme('document-open'), '&Youtube下载器', self, triggered=self.popDnld)
        fileMenu.addAction(downloadAction)
        exitAction = QAction(QIcon.fromTheme('application-exit'), '&退出', self, shortcut='Ctrl+Q', triggered=self.close)
        fileMenu.addAction(exitAction)

        playMenu = self.menuBar().addMenu('&功能')
        self.playIcon = self.style().standardIcon(QStyle.SP_MediaPlay)
        self.pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause)
        self.playAction = toolBar.addAction(self.playIcon, '播放')
        self.playAction.triggered.connect(self.mediaPlay)
        self.volumeIcon = self.style().standardIcon(QStyle.SP_MediaVolume)
        self.volumeMuteIcon = self.style().standardIcon(QStyle.SP_MediaVolumeMuted)
        self.volumeAction = toolBar.addAction(self.volumeIcon, '静音')
        self.volumeAction.triggered.connect(self.volumeMute)
        previewAction = QAction(QIcon.fromTheme('document-open'), '&设置预览字幕', self, triggered=self.popPreview)
        playMenu.addAction(previewAction)

        decodeMenu = self.menuBar().addMenu('&输出')
        decodeAction = QAction(QIcon.fromTheme('document-open'), '&输出字幕及视频', self, triggered=self.decode)
        decodeMenu.addAction(decodeAction)

        self.volSlider = Slider()
        self.volSlider.setOrientation(Qt.Horizontal)
        self.volSlider.setMinimum(0)
        self.volSlider.setMaximum(100)
        self.volSlider.setFixedWidth(120)
        self.volSlider.setValue(self.player.volume())
        self.volSlider.setToolTip(str(self.volSlider.value()))
        self.volSlider.pointClicked.connect(self.setVolume)
        toolBar.addWidget(self.volSlider)

        self.videoPositionEdit = LineEdit('00:00')
        self.videoPositionEdit.setAlignment(Qt.AlignRight)
        self.videoPositionEdit.setFixedWidth(75)
        self.videoPositionEdit.setFont(QFont('Timers', 14))
        self.videoPositionEdit.clicked.connect(self.mediaPauseOnly)
        self.videoPositionEdit.editingFinished.connect(self.mediaPlayOnly)
        self.videoPositionLabel = QLabel(' / 00:00  ')
        self.videoPositionLabel.setFont(QFont('Timers', 14))
        toolBar.addWidget(QLabel('    '))
        toolBar.addWidget(self.videoPositionEdit)
        toolBar.addWidget(self.videoPositionLabel)

        self.timer = QTimer()
        self.timer.setInterval(100)
        self.videoSlider = Slider()
        self.videoSlider.setEnabled(False)
        self.videoSlider.setOrientation(Qt.Horizontal)
        self.videoSlider.setMinimum(0)
        self.videoSlider.setMaximum(1000)
        self.videoSlider.setFixedWidth(1000)
        self.videoSlider.sliderMoved.connect(self.timeStop)
        self.videoSlider.sliderReleased.connect(self.timeStart)
        self.videoSlider.pointClicked.connect(self.videoSliderClick)
        toolBar.addWidget(self.videoSlider)

        toolBar.addWidget(QLabel('   '))
        self.globalIntervalComBox = QComboBox()
        self.globalIntervalComBox.addItems(['间隔 100ms', '间隔 200ms', '间隔 500ms', '间隔 1s'])
        self.globalIntervalComBox.setCurrentIndex(1)
        self.globalIntervalComBox.currentIndexChanged.connect(self.setGlobalInterval)
        toolBar.addWidget(self.globalIntervalComBox)
        toolBar.addWidget(QLabel('  '))
        self.subEditComBox = QComboBox()
        self.refreshComboBox()
        toolBar.addWidget(self.subEditComBox)
        toolBar.addWidget(QLabel('  '))
        moveForward = QPushButton('- 1')
        moveForward.setFixedWidth(50)
        toolBar.addWidget(moveForward)
        toolBar.addWidget(QLabel('  '))
        moveAfterward = QPushButton('+ 1')
        moveAfterward.setFixedWidth(50)
        toolBar.addWidget(moveAfterward)
        toolBar.addWidget(QLabel('  '))
        clearSub = QPushButton('清空')
        clearSub.setFixedWidth(50)
        toolBar.addWidget(clearSub)
        toolBar.addWidget(QLabel('  '))
        outputSub = QPushButton('裁剪')
        outputSub.setFixedWidth(50)
        toolBar.addWidget(outputSub)
        moveForward.clicked.connect(self.moveForward)
        moveAfterward.clicked.connect(self.moveAfterward)
        clearSub.clicked.connect(self.clearSub)
        outputSub.clicked.connect(self.exportSubWindow)

    def setGlobalInterval(self, index):
        if not self.playStatus:
            self.mediaPlay()
        self.globalInterval = {0: 100, 1: 200, 2: 500, 3: 1000}[index]
        self.initSubtitle()
        self.initProcess.show()
        self.subtitle.cellChanged.disconnect(self.subEdit)
        for index, subData in self.subtitleDict.items():
            for start, rowData in subData.items():
                startRow = start // self.globalInterval
                deltaRow = rowData[0] // self.globalInterval
                if deltaRow:
                    endRow = startRow + deltaRow
                    for row in range(startRow, endRow):
                        self.subtitle.setItem(row, index, QTableWidgetItem(rowData[1]))
                        if row >= 0:
                            self.subtitle.item(row, index).setBackground(QBrush(QColor('#35545d')))
                    self.subtitle.setSpan(startRow, index, endRow - startRow, 1)
        self.subtitle.cellChanged.connect(self.subEdit)
        self.initProcess.hide()

    def moveForward(self):
        self.initProcess.show()
        self.subtitle.cellChanged.disconnect(self.subEdit)
        index = self.subEditComBox.currentIndex()
        for y in range(self.subtitle.rowCount()):
            self.subtitle.setSpan(y, index, 1, 1)
            self.subtitle.setItem(y, index, QTableWidgetItem(''))
            self.subtitle.item(y, index).setBackground(QBrush(QColor('#232629')))
        tmpDict = self.subtitleDict[index]
        self.subtitleDict[index] = {}
        for start, rowData in tmpDict.items():
            self.subtitleDict[index][start - self.globalInterval] = rowData
        for start, rowData in self.subtitleDict[index].items():
            startRow = start // self.globalInterval
            endRow = startRow + rowData[0] // self.globalInterval
            for row in range(startRow, endRow):
                self.subtitle.setItem(row, index, QTableWidgetItem(rowData[1]))
                self.subtitle.item(row, index).setBackground(QBrush(QColor('#35545d')))
            self.subtitle.setSpan(startRow, index, endRow - startRow, 1)
        self.subtitle.cellChanged.connect(self.subEdit)
        self.initProcess.hide()

    def moveAfterward(self):
        self.initProcess.show()
        self.subtitle.cellChanged.disconnect(self.subEdit)
        index = self.subEditComBox.currentIndex()
        for y in range(self.subtitle.rowCount()):
            self.subtitle.setSpan(y, index, 1, 1)
            self.subtitle.setItem(y, index, QTableWidgetItem(''))
            self.subtitle.item(y, index).setBackground(QBrush(QColor('#232629')))
        tmpDict = self.subtitleDict[index]
        self.subtitleDict[index] = {}
        for start, rowData in tmpDict.items():
            self.subtitleDict[index][start + self.globalInterval] = rowData
        for start, rowData in self.subtitleDict[index].items():
            startRow = start // self.globalInterval
            endRow = startRow + rowData[0] // self.globalInterval
            for row in range(startRow, endRow):
                self.subtitle.setItem(row, index, QTableWidgetItem(rowData[1]))
                self.subtitle.item(row, index).setBackground(QBrush(QColor('#35545d')))
            self.subtitle.setSpan(startRow, index, endRow - startRow, 1)
        self.subtitle.cellChanged.connect(self.subEdit)
        self.initProcess.hide()

    def clearSub(self):
        index = self.subEditComBox.currentIndex()
        reply = QMessageBox.information(self, '清空字幕', '清空第 %s 列字幕条?' % (index + 1), QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.initProcess.show()
            self.subtitle.cellChanged.disconnect(self.subEdit)
            self.subtitleDict[index] = {0: [self.globalInterval, '']}
            for i in range(self.subtitle.rowCount()):
                self.subtitle.setSpan(i, index, 1, 1)
                self.subtitle.setItem(i, index, QTableWidgetItem(''))
                self.subtitle.item(i, index).setBackground(QBrush(QColor('#232629')))
                self.subtitle.setHorizontalHeaderItem(index, QTableWidgetItem('%s' % (index + 1)))
            self.subtitle.cellChanged.connect(self.subEdit)
            self.initProcess.hide()

    def exportSubWindow(self, start=0, end=0, index=None):
        self.releaseKeyboard()
        self.exportWindow.hide()
        self.exportWindow.show()
        start = '00:00.0' if not start else self.splitTime(start)
        end = self.splitTime(self.duration) if not end else self.splitTime(end)
        if not index:
            index = self.subEditComBox.currentIndex() + 1
        self.exportWindow.setDefault(start, end, index)

    def exportSubtitle(self, exportArgs):
        start = calSubTime2(exportArgs[0])
        end = calSubTime2(exportArgs[1])
        subStart = calSubTime2(exportArgs[2])
        index = exportArgs[3] - 1
        subData = self.subtitleDict[index]
        rowList = sorted(subData.keys())
        exportRange = []
        for t in rowList:
            if t >= start and t <= end:
                exportRange.append(t)
        subNumber = 1
        with open(exportArgs[-1], 'w', encoding='utf-8') as exportFile:
            for t in exportRange:
                text = subData[t][1]
                if text:
                    start = ms2Time(t + subStart)
                    end = ms2Time(t + subStart + subData[t][0])
                    exportFile.write('%s\n%s --> %s\n%s\n\n' % (subNumber, start, end, text))
                    subNumber += 1
        QMessageBox.information(self, '导出字幕', '导出完成', QMessageBox.Yes)
        self.exportWindow.hide()

    def refreshComboBox(self):
        self.subEditComBox.clear()
        for i in range(self.subtitle.columnCount()):
            self.subEditComBox.addItem('字幕 ' + str(i + 1))

    def open(self):
        self.videoPath = QFileDialog.getOpenFileName(self, "请选择视频文件", None, "MP4格式 (*.mp4);;所有文件(*.*)")[0]
        if self.videoPath:
            cmd = ['utils/ffmpeg.exe', '-i', self.videoPath]
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            p.wait()
            for l in p.stdout.readlines():
                l = l.decode('utf8')
                if 'Duration' in l:
                    self.duration = calSubTime(l.split(' ')[3][:-1])
                if 'Stream' in l and 'DAR' in l:
                    self.videoWidth, self.videoHeight = map(int, l.split(' [')[0].split(' ')[-1].split('x'))
                    args = l.split(',')
                    for cnt, arg in enumerate(args):
                        if 'kb' in arg:
                            self.bitrate = int(arg.split('kb')[0])
                            self.fps = int(args[cnt + 1].split('fps')[0])
                            break
                    break
            self.initProcess.show()
            self.subtitle.cellChanged.disconnect(self.subEdit)
            self.subtitle.setRowCount(self.duration // self.globalInterval + 1)
            self.subtitle.setVerticalHeaderLabels([cnt2Time2(i, self.globalInterval) for i in range(self.subtitle.rowCount())])
            self.subtitle.cellChanged.connect(self.subEdit)
            self.initProcess.hide()
            url = QUrl.fromLocalFile(self.videoPath)
            self.stack.setCurrentIndex(1)
            self.playerWidget.setSize(QSizeF(1280, 720))
            self.player.setMedia(url)
            self.playStatus = True
            self.videoSlider.setEnabled(True)
            self.mediaPlay()
            self.timer.start()
            self.timer.timeout.connect(self.timeOut)
            self.subTimer.start()
            self.subTimer.timeout.connect(self.subTimeOut)

    def popDnld(self):
        self.releaseKeyboard()
        self.dnldWindow.hide()
        self.dnldWindow.show()

    def popPreview(self):
        self.releaseKeyboard()
        self.previewSubtitle.hide()
        self.previewSubtitle.show()

    def decode(self):
        self.releaseKeyboard()
        self.videoDecoder.setDefault(self.videoPath, self.videoWidth, self.videoHeight, self.duration, self.bitrate, self.fps, self.subtitleDict)
        self.videoDecoder.hide()
        self.videoDecoder.show()

    def mediaPlay(self):
        if self.playStatus:
            self.player.play()
            self.grabKeyboard()
            self.timeStart()
            self.playStatus = False
            self.playAction.setIcon(self.pauseIcon)
            self.playAction.setText('暂停')
        else:
            self.player.pause()
            self.timeStop()
            self.playStatus = True
            self.playAction.setIcon(self.playIcon)
            self.playAction.setText('播放')

    def mediaPlayOnly(self):
        self.grabKeyboard()
        try:
            timeText = self.videoPositionEdit.text().split(':')
            m, s = timeText[:2]
            if not m:
                m = '00'
            if not s:
                s = '00'
            if len(m) > 3:
                m = m[:3]
            if len(s) > 2:
                s = s[:2]
            if m.isdigit():
                m = int(m)
            if s.isdigit():
                s = int(s)
            if s > 60:
                s = 60
            total_m = self.player.duration() // 60000
            if m > total_m:
                m = total_m
            self.player.setPosition(m * 60000 + s * 1000)
            self.videoSlider.setValue(self.player.position() * 1000 / self.player.duration())
        except:
            pass
        self.videoPositionEdit.setReadOnly(True)
        self.timeStart()

    def mediaPauseOnly(self):
        self.releaseKeyboard()
        self.videoPositionEdit.setReadOnly(False)
        self.player.pause()
        self.timeStop()
        self.playStatus = True
        self.playAction.setIcon(self.playIcon)
        self.playAction.setText('播放')

    def splitTime(self, playTime):
        playTime = playTime // 1000
        m = str(playTime // 60)
        s = playTime % 60
        s = ('0%s' % s)[-2:]
        if len(m) > 2:
            t = '%3s:%2s' % (m, s)
        else:
            t = '%2s:%2s' % (m, s)
        return t

    def timeOut(self):
        row = self.player.position() // self.globalInterval
        self.subtitle.selectRow(row)
        self.subtitle.verticalScrollBar().setValue(row - 10)
        if self.dnldWindow.isHidden() or self.exportWindow.isHidden() or self.videoDecoder.isHidden():
            self.grabKeyboard()
        try:
            self.videoSlider.setValue(self.player.position() * 1000 / self.player.duration())
            self.setTimeLabel()
        except:
            pass

    def timeStop(self):
        self.timer.stop()

    def timeStart(self):
        self.timer.start()

    def videoSliderClick(self, p):
        self.videoSlider.setValue(p.x())
        self.player.setPosition(p.x() * self.player.duration() // 1000)
        self.setTimeLabel()

    def setVolume(self, p):
        self.volumeValue = p.x()
        if self.volumeValue > 100:
            self.volumeValue = 100
        if self.volumeValue < 0:
            self.volumeValue = 0
        self.volSlider.setValue(self.volumeValue)
        self.player.setVolume(self.volumeValue)
        self.volSlider.setToolTip(str(self.volSlider.value()))
        if self.volumeValue:
            self.volumeStatus = True
            self.volumeAction.setIcon(self.volumeIcon)
        else:
            self.volumeStatus = False
            self.volumeAction.setIcon(self.volumeMuteIcon)

    def volumeMute(self):
        if self.volumeStatus:
            self.volumeStatus = False
            self.old_volumeValue = self.player.volume()
            self.player.setVolume(0)
            self.volSlider.setValue(0)
            self.volumeAction.setIcon(self.volumeMuteIcon)
        else:
            self.volumeStatus = True
            self.player.setVolume(self.old_volumeValue)
            self.volSlider.setValue(self.old_volumeValue)
            self.volumeAction.setIcon(self.volumeIcon)

    def setTimeLabel(self):
        now = self.player.position()
        total = self.player.duration()
        now = self.splitTime(now)
        total = self.splitTime(total)
        self.videoPositionEdit.setText(now)
        self.videoPositionLabel.setText(' / %s  ' % total)

    def eventFilter(self, obj, event):
        if obj == self.view:
            if event.type() == QEvent.MouseButtonPress:
                self.mediaPlay()
        return QMainWindow.eventFilter(self, obj, event)

    def keyPressEvent(self, QKeyEvent):
        key = QKeyEvent.key()
        if key == Qt.Key_Left:
            if self.videoSlider.isEnabled():
                self.player.setPosition(self.player.position() - 5000)
                self.videoSlider.setValue(self.player.position() * 1000 / self.player.duration())
                self.setTimeLabel()
        elif key == Qt.Key_Right:
            if self.videoSlider.isEnabled():
                self.player.setPosition(self.player.position() + 5000)
                self.videoSlider.setValue(self.player.position() * 1000 / self.player.duration())
                self.setTimeLabel()
        elif key == Qt.Key_Up:
            self.volumeValue += 10
            if self.volumeValue > 100:
                self.volumeValue = 100
            self.volSlider.setValue(self.volumeValue)
            self.player.setVolume(self.volumeValue)
        elif key == Qt.Key_Down:
            self.volumeValue -= 10
            if self.volumeValue < 0:
                self.volumeValue = 0
            self.volSlider.setValue(self.volumeValue)
            self.player.setVolume(self.volumeValue)
        elif key == Qt.Key_Space:
            self.mediaPlay()
示例#4
0
class EntityViewer(QWidget):
    def __init__(self, parent, entity):
        self.parent = parent
        QWidget.__init__(self)
        self.entity = entity
        self.initUI()

    def initUI(self):
        self.layout = QGridLayout(self)
        self.setLayout(self.layout)

        self.back = QPushButton("Back")
        self.back.clicked.connect(self.chooseotherentity)
        self.layout.addWidget(self.back, 0, 0)

        self.pullb = QPushButton("Reload from Shotgun")
        self.pullb.clicked.connect(self.pull)
        self.layout.addWidget(self.pullb, 2, 0)

        self.savePage = QPushButton("Save Page")
        self.savePage.clicked.connect(self.setPageSettings)
        self.layout.addWidget(self.savePage, 3, 0)

        self.grid = QTableWidget(self)
        self.layout.addWidget(self.grid, 1, 0)
        self.grid.cellDoubleClicked.connect(self.edit)
        self.grid.cellClicked.connect(self.unedit)
        self.activeCell = None
        self.initData()
        self.grid.horizontalHeader().setSectionsMovable(True)
        self.grid.horizontalHeader().setContextMenuPolicy(Qt.CustomContextMenu)

        self.grid.horizontalHeader().customContextMenuRequested.connect(
            self.hideF)

    def initData(self):
        self.entdata = self.parent.parent.db.get(self.entity)
        self.fieldsToShow = self.sanitizeFields(self.entdata)
        i = 0
        indexMap = {}
        for field in self.fieldsToShow:
            self.grid.insertColumn(self.grid.columnCount())
            self.grid.setHorizontalHeaderItem(i, QTableWidgetItem(field))
            indexMap[field] = i
            i += 1
        for ent in self.entdata.data:
            self.grid.insertRow(self.grid.rowCount())
            for field in ent:
                if field in indexMap:
                    cell = cellmanager.barfCell(ent[field], self.parent)
                    self.grid.setCellWidget(self.grid.rowCount() - 1,
                                            indexMap[field], cell)

    def edit(self, row, column):
        newCell = cellmanager.edit(self.grid.cellWidget(row, column))
        if newCell:
            self.grid.setCellWidget(row, column, newCell)
            self.activeCell = (row, column)

    def unedit(self, row, column):  #pylint:disable=unused-argument
        if self.activeCell:
            self.grid.setCellWidget(
                self.activeCell[0], self.activeCell[1],
                cellmanager.save(
                    self.grid.cellWidget(self.activeCell[0],
                                         self.activeCell[1])))
            self.activeCell = None

    def chooseotherentity(self):
        self.parent.parent.changeState(self.parent)

    def pull(self):
        self.parent.parent.db.reloadTable(self.entity)
        self.parent.parent.changeState(EntityViewer(self.parent, self.entity))

    def hideF(self, position):
        menu = QMenu()
        hideField = menu.addAction("Hide")
        ac = menu.exec_(self.grid.mapToGlobal(position))
        if ac == hideField:
            index = self.grid.horizontalHeader().logicalIndexAt(position)
            self.grid.removeColumn(index)

    def setPageSettings(self):
        rules = []
        for i in range(0, self.grid.columnCount()):
            rules.append(
                self.grid.horizontalHeaderItem(
                    self.grid.horizontalHeader().visualIndex(i)).text())
        json_reader.write(rules, "data/pagesettings/%s" % self.entity)

    def sanitizeFields(self, allData):
        try:
            rules = json_reader.read("data/pagesettings/%s" % self.entity)
        except IOError:
            print("No page settings saved for %ss." % self.entity)
            return allData.data[0]
        return rules
示例#5
0
class StreamFieldsWidget(QDialog):
    """
    A stream widget containing schema-specific properties.
    """
    def __init__(self, parent, show_only_f142_stream: bool = False):
        super().__init__()
        self.setParent(parent)
        self.setLayout(QGridLayout())
        self.setWindowModality(Qt.WindowModal)
        self.setModal(True)

        self._show_only_f142_stream = show_only_f142_stream
        self.minimum_spinbox_value = 0
        self.maximum_spinbox_value = 100_000_000
        self.advanced_options_enabled = False

        self.hs00_unimplemented_label = QLabel(
            "hs00 (Event histograms) has not yet been fully implemented.")

        self.schema_label = QLabel("Schema: ")
        self.schema_combo = DropDownList()
        self.schema_validator = SchemaSelectionValidator()
        self.schema_combo.setValidator(self.schema_validator)
        self.schema_validator.is_valid.connect(
            partial(validate_general_widget, self.schema_combo))

        self.topic_label = QLabel("Topic: ")
        self.topic_line_edit = QLineEdit()
        self.topic_validator = NoEmptyStringValidator()
        self.topic_line_edit.setValidator(self.topic_validator)
        self.topic_validator.is_valid.connect(
            partial(
                validate_line_edit,
                self.topic_line_edit,
                tooltip_on_reject="Topic name can not be empty.",
            ))
        validate_line_edit(self.topic_line_edit, False)

        self.source_label = QLabel("Source: ")
        self.source_line_edit = QLineEdit()
        self.source_validator = NoEmptyStringValidator()
        self.source_line_edit.setValidator(self.source_validator)
        self.source_validator.is_valid.connect(
            partial(
                validate_line_edit,
                self.source_line_edit,
                tooltip_on_reject="Source name can not be empty.",
            ))
        validate_line_edit(self.source_line_edit, False)

        self.array_size_label = QLabel("Array size: ")
        self.array_size_spinbox = QSpinBox()
        self.array_size_spinbox.setMaximum(np.iinfo(np.int32).max)

        self.array_size_table = QTableWidget(1, 3)
        self.array_size_table.setHorizontalHeaderLabels(["x", "y", "z"])
        self.array_size_table.setVerticalHeaderLabels([""])
        table_height = self.array_size_table.sizeHintForRow(
            0) + self.array_size_table.sizeHintForRow(1)
        self.array_size_table.setMaximumHeight(table_height)
        self.array_size_table.setFrameStyle(QFrame.NoFrame)
        self.array_size_table.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.array_size_table.resizeColumnsToContents()
        self.array_size_table.resizeRowsToContents()
        self.array_size_table.setItemDelegate(
            ValueDelegate(int, self.array_size_table))

        self.type_label = QLabel("Type: ")
        self.type_combo = QComboBox()
        self.type_combo.addItems(F142_TYPES)
        self.type_combo.setCurrentText("double")

        self.value_units_edit = QLineEdit()
        self.value_units_label = QLabel("Value Units:")

        self.show_advanced_options_button = QPushButton(
            text="Show/hide advanced options")
        self.show_advanced_options_button.setCheckable(True)
        self.show_advanced_options_button.clicked.connect(
            self.advanced_options_button_clicked)

        self._set_up_f142_group_box()
        self._set_up_ev42_group_box()

        self.scalar_radio = QRadioButton(text=SCALAR)
        self.scalar_radio.clicked.connect(partial(self._show_array_size,
                                                  False))
        self.scalar_radio.setChecked(True)
        self.scalar_radio.clicked.emit()

        self.array_radio = QRadioButton(text=ARRAY)
        self.array_radio.clicked.connect(partial(self._show_array_size, True))

        self.schema_combo.currentTextChanged.connect(self._schema_type_changed)
        if self._show_only_f142_stream:
            self.schema_combo.addItems([StreamModules.F142.value])
        else:
            self.schema_combo.addItems([e.value for e in StreamModules])

        self.ok_button = QPushButton("OK")
        self.ok_button.clicked.connect(self.parent().close)

        self.layout().addWidget(self.schema_label, 0, 0)
        self.layout().addWidget(self.schema_combo, 0, 1)

        self.layout().addWidget(self.topic_label, 1, 0)
        self.layout().addWidget(self.topic_line_edit, 1, 1)

        self.layout().addWidget(self.source_label, 2, 0)
        self.layout().addWidget(self.source_line_edit, 2, 1)

        self.layout().addWidget(self.value_units_label, 3, 0)
        self.layout().addWidget(self.value_units_edit, 3, 1)
        self.value_units_label.setVisible(False)
        self.value_units_edit.setVisible(False)

        self.layout().addWidget(self.type_label, 4, 0)
        self.layout().addWidget(self.type_combo, 4, 1)

        self.layout().addWidget(self.scalar_radio, 5, 0)
        self.layout().addWidget(self.array_radio, 5, 1)

        self.layout().addWidget(self.array_size_label, 6, 0)
        self.layout().addWidget(self.array_size_spinbox, 6, 1)
        self.layout().addWidget(self.array_size_table, 6, 1)

        self.layout().addWidget(self.hs00_unimplemented_label, 7, 0, 1, 2)

        # Spans both rows
        self.layout().addWidget(self.show_advanced_options_button, 8, 0, 1, 2)
        self.layout().addWidget(self.f142_advanced_group_box, 9, 0, 1, 2)

        self.layout().addWidget(self.ev42_advanced_group_box, 10, 0, 1, 2)

        self.layout().addWidget(self.ok_button, 11, 0, 1, 2)

        self._schema_type_changed(self.schema_combo.currentText())
        self.parent().parent().field_name_edit.setVisible(False)

    def advanced_options_button_clicked(self):
        self._show_advanced_options(
            show=self.show_advanced_options_button.isChecked())

    def _set_up_ev42_group_box(self):
        """
        Sets up the UI for ev42 advanced options.
        """
        self.ev42_advanced_group_box = QGroupBox(
            parent=self.show_advanced_options_button)
        self.ev42_advanced_group_box.setLayout(QFormLayout())

        self.ev42_adc_pulse_debug_label = QLabel(ADC_PULSE_DEBUG)
        self.ev42_adc_pulse_debug_checkbox = QCheckBox()
        self.ev42_advanced_group_box.layout().addRow(
            self.ev42_adc_pulse_debug_label,
            self.ev42_adc_pulse_debug_checkbox)

        self.ev42_chunk_size_spinner = (
            self.create_label_and_spinbox_for_advanced_option(
                CHUNK_SIZE, self.ev42_advanced_group_box))
        self.ev42_cue_interval_spinner = (
            self.create_label_and_spinbox_for_advanced_option(
                CUE_INTERVAL, self.ev42_advanced_group_box))

    def create_label_and_spinbox_for_advanced_option(self, nexus_string: str,
                                                     group_box: QGroupBox):
        """
        Creates a SpinBox with a label and adds them to GroupBox then returns the SpinBox.
        :param nexus_string: The nexus string label for the SpinBox.
        :param group_box: The GroupBox that the label and SpinBox should be added to.
        :return: The newly created SpinBox.
        """
        label = QLabel(nexus_string)
        spinner = QSpinBox()
        spinner.setRange(self.minimum_spinbox_value,
                         self.maximum_spinbox_value)
        group_box.layout().addRow(label, spinner)

        return spinner

    def _set_up_f142_group_box(self):
        """
        Sets up the UI for the f142 advanced options.
        """
        self.f142_advanced_group_box = QGroupBox(
            parent=self.show_advanced_options_button)
        self.f142_advanced_group_box.setLayout(QFormLayout())
        self.f142_chunk_size_spinner = (
            self.create_label_and_spinbox_for_advanced_option(
                CHUNK_SIZE, self.f142_advanced_group_box))
        self.f142_cue_interval_spinner = (
            self.create_label_and_spinbox_for_advanced_option(
                CUE_INTERVAL, self.f142_advanced_group_box))

    def _show_advanced_options(self, show):
        schema = self.schema_combo.currentText()
        if schema == WriterModules.F142.value:
            self.f142_advanced_group_box.setVisible(show)
        elif schema == WriterModules.EV42.value:
            self.ev42_advanced_group_box.setVisible(show)
        self.advanced_options_enabled = show

    def _show_array_size(self, show: bool):
        self.array_size_spinbox.setVisible(show)
        self.array_size_label.setVisible(show)

    def _schema_type_changed(self, schema: str):
        self.parent().setWindowTitle(f"Editing {schema} stream field")
        self.hs00_unimplemented_label.setVisible(False)
        self.f142_advanced_group_box.setVisible(False)
        self.ev42_advanced_group_box.setVisible(False)
        self.show_advanced_options_button.setVisible(False)
        self.show_advanced_options_button.setChecked(False)
        self.value_units_label.setVisible(False)
        self.value_units_edit.setVisible(False)
        self.array_size_table.setVisible(False)
        if schema == WriterModules.F142.value:
            self.value_units_label.setVisible(True)
            self.value_units_edit.setVisible(True)
            self._set_edits_visible(True, True)
            self.show_advanced_options_button.setVisible(True)
            self.f142_advanced_group_box.setVisible(False)
        elif schema == WriterModules.EV42.value:
            self._set_edits_visible(True, False)
            self.show_advanced_options_button.setVisible(True)
            self.ev42_advanced_group_box.setVisible(False)
        elif schema == WriterModules.ADAR.value:
            self._set_edits_visible(True, False)
            self._show_array_size_table(True)
        elif schema == WriterModules.HS00.value:
            self._set_edits_visible(True, False)
            self.hs00_unimplemented_label.setVisible(True)
        elif schema == WriterModules.NS10.value:
            self._set_edits_visible(True, False, "nicos/<device>/<parameter>")
        elif (schema == WriterModules.TDCTIME.value
              or schema == WriterModules.SENV.value):
            self._set_edits_visible(True, False)

    def _show_array_size_table(self, show: bool):
        self.array_size_label.setVisible(show)
        self.array_size_table.setVisible(show)

    def _set_edits_visible(self, source: bool, type: bool, source_hint=None):
        self.source_label.setVisible(source)
        self.source_line_edit.setVisible(source)
        self.type_label.setVisible(type)
        self.type_combo.setVisible(type)
        self.array_radio.setVisible(type)
        self.scalar_radio.setVisible(type)
        if source_hint:
            self.source_line_edit.setPlaceholderText(source_hint)
        else:
            self.source_line_edit.setPlaceholderText("")

    def get_stream_module(self, parent) -> StreamModule:
        """
        Create the stream module
        :return: The created stream module
        """

        source = self.source_line_edit.text()
        topic = self.topic_line_edit.text()
        stream: StreamModule = None
        type = self.type_combo.currentText()
        current_schema = self.schema_combo.currentText()
        if current_schema == WriterModules.F142.value:
            value_units = self.value_units_edit.text()
            array_size = self.array_size_spinbox.value()
            stream = F142Stream(
                parent_node=parent,
                source=source,
                topic=topic,
                type=type,
                value_units=value_units,
                array_size=array_size,
            )
            if array_size:
                stream.array_size = array_size
            if self.advanced_options_enabled:
                self.record_advanced_f142_values(stream)
        elif current_schema == WriterModules.ADAR.value:
            array_size = []
            for i in range(self.array_size_table.columnCount()):
                table_value = self.array_size_table.item(0, i)
                if table_value:
                    array_size.append(int(table_value.text()))
            stream = ADARStream(parent_node=parent, source=source, topic=topic)
            stream.array_size = array_size
        elif current_schema == WriterModules.EV42.value:
            stream = EV42Stream(parent_node=parent, source=source, topic=topic)
            if self.advanced_options_enabled:
                self.record_advanced_ev42_values(stream)
        elif current_schema == WriterModules.NS10.value:
            stream = NS10Stream(parent_node=parent, source=source, topic=topic)
        elif current_schema == WriterModules.SENV.value:
            stream = SENVStream(parent_node=parent, source=source, topic=topic)
        elif current_schema == WriterModules.HS00.value:
            stream = HS00Stream(  # type: ignore
                parent=parent,
                source=source,
                topic=topic,
                data_type=NotImplemented,
                edge_type=NotImplemented,
                error_type=NotImplemented,
                shape=[],
            )
        elif current_schema == WriterModules.TDCTIME.value:
            stream = TDCTStream(parent_node=parent, source=source, topic=topic)

        return stream

    def record_advanced_f142_values(self, stream: F142Stream):
        """
        Save the advanced f142 properties to the stream data object.
        :param stream: The stream data object to be modified.
        """
        stream.chunk_size = self.f142_chunk_size_spinner.value()
        stream.cue_interval = self.f142_cue_interval_spinner.value()

    def record_advanced_ev42_values(self, stream: EV42Stream):
        """
        Save the advanced ev42 properties to the stream data object.
        :param stream: The stream data object to be modified.
        """
        stream.adc_pulse_debug = self.ev42_adc_pulse_debug_checkbox.isChecked()
        stream.chunk_size = self.ev42_chunk_size_spinner.value()
        stream.cue_interval = self.ev42_cue_interval_spinner.value()

    def fill_in_existing_ev42_fields(self, field: EV42Stream):
        """
        Fill in specific existing ev42 fields into the new UI field.
        :param field: The stream group
        """
        if check_if_advanced_options_should_be_enabled(
            [field.adc_pulse_debug, field.chunk_size, field.cue_interval]):
            self._show_advanced_options(True)
            self._fill_existing_advanced_ev42_fields(field)

    def _fill_existing_advanced_ev42_fields(self, field: EV42Stream):
        """
        Fill the fields in the interface with the existing ev42 stream data.
        :param field: The ev42 stream data object.
        """
        self.ev42_adc_pulse_debug_checkbox.setChecked(field.adc_pulse_debug)
        self.ev42_chunk_size_spinner.setValue(field.chunk_size)
        self.ev42_cue_interval_spinner.setValue(field.cue_interval)

    def fill_in_existing_f142_fields(self, field: F142Stream):
        """
        Fill in specific existing f142 fields into the new UI field.
        :param field: The stream group
        """
        self.type_combo.setCurrentText(field.type)
        if field.array_size is not None:
            self.array_radio.setChecked(True)
            self.scalar_radio.setChecked(False)
            self.array_size_spinbox.setValue(field.array_size)
        else:
            self.array_radio.setChecked(False)
            self.scalar_radio.setChecked(True)
        if field.value_units is not None:
            self.value_units_edit.setText(field.value_units)

        if check_if_advanced_options_should_be_enabled(
            [field.chunk_size, field.cue_interval]):
            self._show_advanced_options(True)
            self._fill_existing_advanced_f142_fields(field)

    def _fill_existing_advanced_f142_fields(self, field: F142Stream):
        """
        Fill the advanced fields in the interface with the existing f142 stream data.
        :param field: The f412 stream data object.
        """
        self.f142_chunk_size_spinner.setValue(field.chunk_size)
        self.f142_cue_interval_spinner.setValue(field.cue_interval)

    def update_existing_stream_info(self, field):
        """
        Fill in stream fields and properties into the new UI field.
        :param field: The stream group
        """
        if isinstance(field, Group):
            field = field.children[0]
        if hasattr(field, "parent_node") and isinstance(
                field.parent_node, Group):
            self.schema_validator.set_group(field.parent_node)
        else:
            self.schema_validator.set_group(None)
        schema = field.writer_module
        self.schema_combo.setCurrentText(schema)
        self.schema_validator.validate(schema, 0)
        self.topic_line_edit.setText(field.topic)
        self.topic_validator.validate(field.topic, 0)
        self.source_line_edit.setText(field.source)
        self.source_validator.validate(field.source, 0)
        if schema == WriterModules.F142.value:
            self.fill_in_existing_f142_fields(field)
        elif schema == WriterModules.EV42.value:
            self.fill_in_existing_ev42_fields(field)
        elif schema == WriterModules.ADAR.value:
            for i, val in enumerate(field.array_size):
                self.array_size_table.setItem(0, i, QTableWidgetItem(str(val)))
示例#6
0
class Ui_Whatspy(object):
    def setupUi(self, Ventana):
        if not Ventana.objectName():
            Ventana.setObjectName(u"Ventana")
        Ventana.resize(424, 600)
        Ventana.setAttribute(Qt.WA_TranslucentBackground)
        Ventana.setWindowFlag(Qt.FramelessWindowHint)
        Ventana.setStyleSheet(
            u"*{\n"
            "	font-family: century gothic;\n"
            "}\n"
            "\n"
            "QSizeGrip{\n"
            "       background: transparent;\n"
            "}\n"
            "\n"
            "QLabel{\n"
            "	color: white;\n"
            "}\n"
            "\n"
            "QScrollBar:vertical {\n"
            "            border: 1px solid #999999;\n"
            "            width:12px;    \n"
            "            margin: 0px 0px 0px 0px;\n"
            "        }\n"
            "        QScrollBar::handle:vertical {         \n"
            "       \n"
            "            min-height: 0px;\n"
            "          	border: 0px solid red;\n"
            "			border-radius: 4px;\n"
            "			background-color: rgb(182, 182, 182);\n"
            "        }\n"
            "        QScrollBar::add-line:vertical {       \n"
            "            height: 0px;\n"
            "            subcontrol-position: bottom;\n"
            "            subcontrol-origin: margin;\n"
            "        }\n"
            "        QScrollBar::sub-line:vertical {\n"
            "            height: 0 px;\n"
            "            subcontrol-position: top;\n"
            "            subcontrol-origin: margin;\n"
            "        }")
        self.gridLayout = QGridLayout(Ventana)
        self.gridLayout.setObjectName(u"gridLayout")
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.VentanaFrame = QFrame(Ventana)
        self.VentanaFrame.setObjectName(u"VentanaFrame")
        self.VentanaFrame.setStyleSheet(
            u"QFrame#VentanaFrame{\n"
            "	background-color: qlineargradient(spread:pad, x1:0.953, y1:1, x2:1, y2:0, stop:0 	#075E54, stop:1 #128C7E);\n"
            "	border-radius: 5px;\n"
            "}")
        self.VentanaFrame.setFrameShape(QFrame.StyledPanel)
        self.VentanaFrame.setFrameShadow(QFrame.Raised)
        self.gridLayout_2 = QGridLayout(self.VentanaFrame)
        self.gridLayout_2.setObjectName(u"gridLayout_2")
        self.gridLayout_2.setContentsMargins(-1, 0, -1, -1)
        self.Contenedor = QFrame(self.VentanaFrame)
        self.Contenedor.setObjectName(u"Contenedor")
        self.Contenedor.setStyleSheet(u"QFrame#Contenedor{\n"
                                      "	background-color: #128C7E;\n"
                                      "	border-radius: 5px;\n"
                                      "}")
        self.Contenedor.setFrameShape(QFrame.StyledPanel)
        self.Contenedor.setFrameShadow(QFrame.Raised)
        self.gridLayout_5 = QGridLayout(self.Contenedor)
        self.gridLayout_5.setObjectName(u"gridLayout_5")
        self.gridLayout_5.setContentsMargins(0, 10, 0, 10)
        self.frameAcciones = QFrame(self.Contenedor)
        self.frameAcciones.setObjectName(u"frameAcciones")
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.frameAcciones.sizePolicy().hasHeightForWidth())
        self.frameAcciones.setSizePolicy(sizePolicy)
        self.frameAcciones.setStyleSheet(u"")
        self.frameAcciones.setFrameShape(QFrame.StyledPanel)
        self.frameAcciones.setFrameShadow(QFrame.Raised)
        self.gridLayout_4 = QGridLayout(self.frameAcciones)
        self.gridLayout_4.setObjectName(u"gridLayout_4")
        self.btnExportar = QPushButton(self.frameAcciones)
        self.btnExportar.setObjectName(u"btnExportar")
        sizePolicy1 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
        sizePolicy1.setHorizontalStretch(0)
        sizePolicy1.setVerticalStretch(0)
        sizePolicy1.setHeightForWidth(
            self.btnExportar.sizePolicy().hasHeightForWidth())
        self.btnExportar.setSizePolicy(sizePolicy1)
        self.btnExportar.setMinimumSize(QSize(100, 30))
        self.btnExportar.setCursor(QCursor(Qt.PointingHandCursor))
        self.btnExportar.setStyleSheet(u"QPushButton#btnExportar{\n"
                                       "background-color: #ecf0f1;\n"
                                       "border-radius: 5px;\n"
                                       "}\n"
                                       "\n"
                                       "QPushButton#btnExportar:hover{\n"
                                       "background-color: #bdc3c7;\n"
                                       "border-radius: 5px;\n"
                                       "}")
        icon1 = QIcon()
        icon1.addFile(u":/logo/exportar.png", QSize(), QIcon.Normal, QIcon.Off)
        self.btnExportar.setIcon(icon1)
        self.btnExportar.setIconSize(QSize(16, 16))

        self.gridLayout_4.addWidget(self.btnExportar, 0, 2, 1, 1)

        self.btnAbrir = QPushButton(self.frameAcciones)
        self.btnAbrir.setObjectName(u"btnAbrir")
        sizePolicy1.setHeightForWidth(
            self.btnAbrir.sizePolicy().hasHeightForWidth())
        self.btnAbrir.setSizePolicy(sizePolicy1)
        self.btnAbrir.setMinimumSize(QSize(100, 30))
        self.btnAbrir.setCursor(QCursor(Qt.PointingHandCursor))
        self.btnAbrir.setStyleSheet(u"QPushButton#btnAbrir{\n"
                                    "background-color: #ecf0f1;\n"
                                    "border-radius: 5px;\n"
                                    "}\n"
                                    "\n"
                                    "QPushButton#btnAbrir:hover{\n"
                                    "background-color: #bdc3c7;\n"
                                    "}")
        icon2 = QIcon()
        icon2.addFile(u":/logo/anadir.png", QSize(), QIcon.Normal, QIcon.Off)
        self.btnAbrir.setIcon(icon2)
        self.btnAbrir.setIconSize(QSize(16, 16))

        self.gridLayout_4.addWidget(self.btnAbrir, 0, 1, 1, 1)

        self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.gridLayout_4.addItem(self.horizontalSpacer_2, 0, 0, 1, 1)

        self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.gridLayout_4.addItem(self.horizontalSpacer_3, 0, 3, 1, 1)

        self.gridLayout_5.addWidget(self.frameAcciones, 2, 0, 1, 1)

        self.frameTabla = QFrame(self.Contenedor)
        self.frameTabla.setObjectName(u"frameTabla")
        sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy2.setHorizontalStretch(0)
        sizePolicy2.setVerticalStretch(0)
        sizePolicy2.setHeightForWidth(
            self.frameTabla.sizePolicy().hasHeightForWidth())
        self.frameTabla.setSizePolicy(sizePolicy2)
        self.frameTabla.setStyleSheet(u"")
        self.frameTabla.setFrameShape(QFrame.StyledPanel)
        self.frameTabla.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_2 = QHBoxLayout(self.frameTabla)
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalSpacer_4 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_2.addItem(self.horizontalSpacer_4)

        self.tableWidget = QTableWidget(self.frameTabla)
        if (self.tableWidget.columnCount() < 2):
            self.tableWidget.setColumnCount(2)
        __qtablewidgetitem = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, __qtablewidgetitem)
        __qtablewidgetitem1 = QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, __qtablewidgetitem1)
        if (self.tableWidget.rowCount() < 50):
            self.tableWidget.setRowCount(50)
        __qtablewidgetitem2 = QTableWidgetItem()
        self.tableWidget.setItem(0, 0, __qtablewidgetitem2)
        self.tableWidget.setObjectName(u"tableWidget")
        sizePolicy1.setHeightForWidth(
            self.tableWidget.sizePolicy().hasHeightForWidth())
        self.tableWidget.setSizePolicy(sizePolicy1)
        self.tableWidget.setMinimumSize(QSize(350, 0))
        self.tableWidget.setStyleSheet(u"QTableWidget#tableWidget:item{\n"
                                       "color:white;\n"
                                       "font-weight: bold;\n"
                                       "}\n"
                                       "\n"
                                       "QTableWidget#tableWidget{\n"
                                       "border-radius:4px;\n"
                                       "background-color: #128C7E;\n"
                                       "}")
        self.tableWidget.setRowCount(50)

        self.horizontalLayout_2.addWidget(self.tableWidget)

        self.horizontalSpacer_5 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                              QSizePolicy.Minimum)

        self.horizontalLayout_2.addItem(self.horizontalSpacer_5)

        self.gridLayout_5.addWidget(self.frameTabla, 3, 0, 1, 1)

        self.header = QFrame(self.Contenedor)
        self.header.setObjectName(u"header")
        sizePolicy.setHeightForWidth(
            self.header.sizePolicy().hasHeightForWidth())
        self.header.setSizePolicy(sizePolicy)
        self.header.setStyleSheet(u"")
        self.header.setFrameShape(QFrame.StyledPanel)
        self.header.setFrameShadow(QFrame.Raised)
        self.horizontalLayout = QHBoxLayout(self.header)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 5, 0)
        self.horizontalSpacer = QSpacerItem(0, 0, QSizePolicy.Expanding,
                                            QSizePolicy.Minimum)

        self.horizontalLayout.addItem(self.horizontalSpacer)

        self.btnVerde = QPushButton(self.header)
        self.btnVerde.setObjectName(u"btnVerde")
        self.btnVerde.setMaximumSize(QSize(16, 16))
        self.btnVerde.setCursor(QCursor(Qt.PointingHandCursor))
        self.btnVerde.setStyleSheet(u"QPushButton#btnVerde{\n"
                                    "	background-color: #27ae60;\n"
                                    "	border-radius: 8px;\n"
                                    "}\n"
                                    "\n"
                                    "QPushButton#btnVerde:hover{\n"
                                    "	background-color: #10ac84;\n"
                                    "	border-radius: 8px;\n"
                                    "}")

        self.horizontalLayout.addWidget(self.btnVerde)

        self.btnAmarillo = QPushButton(self.header)
        self.btnAmarillo.setObjectName(u"btnAmarillo")
        self.btnAmarillo.setMaximumSize(QSize(16, 16))
        self.btnAmarillo.setCursor(QCursor(Qt.PointingHandCursor))
        self.btnAmarillo.setStyleSheet(u"QPushButton#btnAmarillo{\n"
                                       "background-color: yellow;\n"
                                       "border-radius: 8px;\n"
                                       "}\n"
                                       "\n"
                                       "QPushButton#btnAmarillo:hover{\n"
                                       "background-color: #f1c40f;\n"
                                       "border-radius: 8px;\n"
                                       "}\n"
                                       "")

        self.horizontalLayout.addWidget(self.btnAmarillo)

        self.btnRojo = QPushButton(self.header)
        self.btnRojo.setObjectName(u"btnRojo")
        self.btnRojo.setMaximumSize(QSize(16, 16))
        self.btnRojo.setCursor(QCursor(Qt.PointingHandCursor))
        self.btnRojo.setStyleSheet(u"QPushButton#btnRojo{\n"
                                   "background-color: red;\n"
                                   "border-radius: 8px;\n"
                                   "}\n"
                                   "\n"
                                   "QPushButton#btnRojo:hover{\n"
                                   "background-color: #e74c3c;\n"
                                   "border-radius: 8px;\n"
                                   "}")

        self.horizontalLayout.addWidget(self.btnRojo)

        self.gridLayout_5.addWidget(self.header, 0, 0, 1, 1)

        self.frameLogo = QFrame(self.Contenedor)
        self.frameLogo.setObjectName(u"frameLogo")
        sizePolicy.setHeightForWidth(
            self.frameLogo.sizePolicy().hasHeightForWidth())
        self.frameLogo.setSizePolicy(sizePolicy)
        self.frameLogo.setStyleSheet(u"")
        self.frameLogo.setFrameShape(QFrame.StyledPanel)
        self.frameLogo.setFrameShadow(QFrame.Raised)
        self.gridLayout_3 = QGridLayout(self.frameLogo)
        self.gridLayout_3.setObjectName(u"gridLayout_3")
        self.lblWhatsPy = QLabel(self.frameLogo)
        self.lblWhatsPy.setObjectName(u"lblWhatsPy")
        font = QFont()
        font.setFamily(u"century gothic")
        font.setBold(True)
        font.setWeight(75)
        self.lblWhatsPy.setFont(font)
        self.lblWhatsPy.setAlignment(Qt.AlignCenter)

        self.gridLayout_3.addWidget(self.lblWhatsPy, 1, 0, 1, 1)

        self.icon = QLabel(self.frameLogo)
        self.icon.setObjectName(u"icon")
        self.icon.setMaximumSize(QSize(70, 70))
        self.icon.setPixmap(QPixmap(u":/logo/logo.png"))
        self.icon.setScaledContents(True)

        self.gridLayout_3.addWidget(self.icon, 0, 0, 1, 1)

        self.gridLayout_5.addWidget(self.frameLogo, 1, 0, 1, 1)

        self.label = QLabel(self.Contenedor)
        self.label.setObjectName(u"label")
        sizePolicy.setHeightForWidth(
            self.label.sizePolicy().hasHeightForWidth())
        self.label.setSizePolicy(sizePolicy)
        self.label.setFont(font)
        self.label.setAlignment(Qt.AlignCenter)

        self.gridLayout_5.addWidget(self.label, 4, 0, 1, 1)

        self.gridLayout_2.addWidget(self.Contenedor, 0, 0, 1, 1)

        self.lblGrip = QLabel(self.VentanaFrame)
        self.lblGrip.setObjectName(u"lblGrip")
        sizePolicy.setHeightForWidth(
            self.lblGrip.sizePolicy().hasHeightForWidth())
        self.lblGrip.setSizePolicy(sizePolicy)
        self.lblGrip.setMaximumSize(QSize(10, 10))
        self.lblGrip.setCursor(QCursor(Qt.BusyCursor))
        self.lblGrip.setLayoutDirection(Qt.RightToLeft)
        self.lblGrip.setStyleSheet(
            u"QLabel#lblGrip:hover{\n"
            "	background: rgb(18, 140, 126);\n"
            "	border-radius: 5px;\n"
            "}\n"
            "\n"
            "QLabel#lblGrip{\n"
            "	background-color: qlineargradient(spread:pad, x1:0.953, y1:1, x2:1, y2:0, stop:0 	#075E54, stop:1 #128C7E);\n"
            "	border-radius: 5px;\n"
            "}")

        self.gridLayout_2.addWidget(self.lblGrip, 1, 0, 1, 1)

        self.gridLayout.addWidget(self.VentanaFrame, 0, 0, 1, 1)

        self.retranslateUi(Ventana)

        QMetaObject.connectSlotsByName(Ventana)

    # setupUi

    def retranslateUi(self, Ventana):
        Ventana.setWindowTitle(
            QCoreApplication.translate("Ventana", u"Form", None))
        self.btnExportar.setText(
            QCoreApplication.translate("Ventana", u"Exportar", None))
        self.btnAbrir.setText(
            QCoreApplication.translate("Ventana", u"Abrir TXT", None))
        ___qtablewidgetitem = self.tableWidget.horizontalHeaderItem(0)
        ___qtablewidgetitem.setText(
            QCoreApplication.translate("Ventana", u"N\u00fameros", None))
        ___qtablewidgetitem1 = self.tableWidget.horizontalHeaderItem(1)
        ___qtablewidgetitem1.setText(
            QCoreApplication.translate("Ventana", u"Mensajes", None))

        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        self.tableWidget.setSortingEnabled(__sortingEnabled)

        self.btnVerde.setText("")
        self.btnAmarillo.setText("")
        self.btnRojo.setText("")
        self.lblWhatsPy.setText(
            QCoreApplication.translate("Ventana", u"WhatsPy", None))
        self.icon.setText("")
        self.label.setText(
            QCoreApplication.translate(
                "Ventana", u"Todav\u00eda no haz cargado ning\u00fan chat",
                None))
        self.lblGrip.setText("")
示例#7
0
class Table(QWidget):
    def __init__(self):
        super().__init__()

        self.layout = QHBoxLayout()
        size = 5
        self.table = QTableWidget(size, size)
        self.table.setMaximumSize(275, 295)
        self.table.setHorizontalHeaderLabels([str(i + 1) + "\n " for i in range(size)])

        self.tableResults = QTableWidget(size, 2)
        self.tableResults.horizontalHeader().setDefaultSectionSize(100)
        self.tableResults.verticalHeader().setDefaultSectionSize(50)
        self.tableResults.setMaximumSize(225, 295)
        self.tableResults.setHorizontalHeaderLabels(["Предельные\nвероятности", "Время\nстабилизации"])

        #self.table.setCellWidget(1000, 1000, self)
        self.table.horizontalHeader().setDefaultSectionSize(50)
        self.table.verticalHeader().setDefaultSectionSize(50)
        #self.table.setCellWidget(200, 200, self.table)
        delegate = IconDelegate(self.table)
        self.table.setItemDelegate(delegate)
        self.tableLayout = QHBoxLayout()
        self.tableLayout.addWidget(self.tableResults)
        tmp = QHBoxLayout()
        tmp.addWidget(self.table)
        tmp.setMargin(10)

        self.tableLayout.addLayout(tmp)
        self.tableLayout.setAlignment(Qt.AlignRight)

        self.panel = QVBoxLayout()

        self.cell = QLineEdit()
        self.cell.setMaximumSize(150, 20)

        self.buttonSize = QPushButton("Задать размер")
        self.buttonSize.setMaximumSize(150, 50)
        self.buttonSize.clicked.connect(self.resizeTable)

        self.buttonCalculate = QPushButton("Вычислить")
        self.buttonCalculate.clicked.connect(self.solve)
        self.buttonCalculate.setMaximumSize(150, 50)

        self.panel.addWidget(self.cell)
        self.panel.addWidget(self.buttonSize)
        self.panel.addWidget(self.buttonCalculate)
        self.panel.setAlignment(Qt.AlignTop)

        self.layout.addLayout(self.panel)
        self.layout.addLayout(self.tableLayout)
        self.layout.setAlignment(Qt.AlignTop)
        #self.layout.setAlignment(Qt.AlignRight)

        self.setLayout(self.layout)


    def resizeTable(self):
        print("fill")
        try:
            size = int(self.cell.text())
        except ValueError:
            print("Wrong value")
            return

        print("resize")
        self.table.setColumnCount(size)
        self.table.setRowCount(size)

        self.tableResults.setRowCount(size)
        self.fillTable(size)

    def fillTable(self, size):
        print("fill")
        self.table.setMaximumSize(size*50 + 25, size*50 + 45)
        self.tableResults.setMaximumSize(225, size * 50 + 45)
        newFont = QFont("Arial", 12)

        for i in range(size):
            for j in range(size):
                if i == j:
                    #self.table.setItem(i, j, QTableWidgetItem(QIcon("sticker.svg"), ""))
                    item = QTableWidgetItem("0")
                    item.setTextAlignment(Qt.AlignCenter)
                    item.setFont(newFont)
                    self.table.setItem(i, j, item)
                else:
                    item = QTableWidgetItem(str(random.randrange(1)))
                    item.setTextAlignment(Qt.AlignCenter)
                    item.setFont(newFont)
                    self.table.setItem(i, j, item)

        self.table.setHorizontalHeaderLabels([str(i + 1) + "\n " for i in range(size)])
        print(self.table.item(0, 1).text())

        for i in range(size):
            for j in range(2):
                    item = QTableWidgetItem("__")
                    item.setTextAlignment(Qt.AlignCenter)
                    item.setFont(newFont)
                    self.tableResults.setItem(i, j, item)

    def solve(self):
        self.calculatProbabilities()
        self.calculateStabilisationTime()

    def calculatProbabilities(self):
        matrix = [[float(self.table.item(j, i).text()) for j in range(self.table.rowCount())]
                  for i in range(self.table.columnCount())]

        for i in range(self.table.columnCount()):
            matrix[i][i] = -sum([matrix[j][i] for j in range(self.table.columnCount())])

        #print(matrix)
        b = [0]*self.table.columnCount()
        b[0] = 1

        matrix[0] = [1 for _ in matrix[0]]
        #print(matrix)
        #print(b)

        a = numpy.array(matrix)
        b = numpy.array(b)
        answ = list(numpy.linalg.solve(a, b))
        #print(answ)

        for i in range(len(answ)):
            self.tableResults.item(i, 0).setText("{:.4f}".format(answ[i]))

    def calculateStabilisationTime(self):
        matrix = [[float(self.table.item(i, j).text()) for j in range(self.table.rowCount())]
                  for i in range(self.table.columnCount())]
        print(matrix)

        start_probabilities = [1/len(matrix[0]) for _ in matrix[0]]
        print(start_probabilities)

        limit_probabilities = calc_limit_probabilities(matrix)
        print(limit_probabilities)

        stabilization_times = calc_stabilization_times(matrix, start_probabilities, limit_probabilities)
        print(stabilization_times)

        for i in range(len(stabilization_times)):
            self.tableResults.item(i, 1).setText("{:.4f}".format(stabilization_times[i]))
示例#8
0
class TableWidget(QWidget):
    def __init__(self,
                 table,
                 headers,
                 bold=True,
                 mono=True,
                 tooltips=None,
                 align=False,
                 search=True,
                 parent=None):
        super(TableWidget, self).__init__(parent)

        self.table_widget = QTableWidget(len(table), len(table[0]))
        for i, row in enumerate(table):
            for j, item in enumerate(row):
                if item is not None:
                    self.table_widget.setItem(i, j,
                                              QTableWidgetItem(str(item)))
                    if tooltips is not None:
                        self.table_widget.setToolTip(tooltips[i][j])
                    modify_font(self.table_widget.item(i, j),
                                bold=bold and j == 0,
                                mono=mono)
                    if align:
                        self.table_widget.item(i, j).setTextAlignment(
                            Qt.AlignRight)

        self.table_headers = headers
        self.table_widget.setHorizontalHeaderLabels(self.table_headers)
        self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_widget.resizeColumnsToContents()
        self.table_widget.setAlternatingRowColors(True)
        self.table_widget.itemDoubleClicked.connect(self.copy)

        search_layout = QHBoxLayout()
        search_layout.addWidget(QLabel(self.tr('Search:')))
        self.search_edit = QLineEdit()
        self.search_edit.textChanged.connect(self.start)
        self.search_edit.returnPressed.connect(self.next)
        search_layout.addWidget(self.search_edit)

        clear_button = QToolButton()
        clear_button.setIcon(QIcon('icons/clear.svg'))
        clear_button.setShortcut(QKeySequence.DeleteCompleteLine)
        clear_button.setToolTip(self.tr('Clear pattern'))
        clear_button.clicked.connect(self.search_edit.clear)
        search_layout.addWidget(clear_button)

        self.case_button = QToolButton()
        self.case_button.setText(self.tr('Aa'))
        self.case_button.setCheckable(True)
        self.case_button.toggled.connect(self.start)
        self.case_button.setToolTip(self.tr('Case sensitive'))
        search_layout.addWidget(self.case_button)

        self.word_button = QToolButton()
        self.word_button.setText(self.tr('W'))
        self.word_button.setCheckable(True)
        self.word_button.toggled.connect(self.start)
        self.word_button.setToolTip(self.tr('Whole words'))
        search_layout.addWidget(self.word_button)

        self.regex_button = QToolButton()
        self.regex_button.setText(self.tr('.*'))
        self.regex_button.setCheckable(True)
        self.regex_button.toggled.connect(self.start)
        self.regex_button.setToolTip(self.tr('Regular expression'))
        search_layout.addWidget(self.regex_button)

        prev_button = QToolButton()
        prev_button.setIcon(QIcon('icons/up.svg'))
        prev_button.setShortcut(QKeySequence.FindPrevious)
        prev_button.clicked.connect(self.previous)
        prev_button.setToolTip(self.tr('Previous occurence'))
        search_layout.addWidget(prev_button)

        next_button = QToolButton()
        next_button.setIcon(QIcon('icons/down.svg'))
        next_button.setShortcut(QKeySequence.FindNext)
        next_button.clicked.connect(self.next)
        next_button.setToolTip(self.tr('Next occurence'))
        search_layout.addWidget(next_button)

        self.matches_label = QLabel()
        search_layout.addWidget(self.matches_label)
        search_layout.addStretch()

        export_button = QToolButton()
        export_button.setText(self.tr('Export...'))
        export_button.clicked.connect(self.export)
        search_layout.addWidget(export_button)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.table_widget)
        if search:
            main_layout.addLayout(search_layout)
        self.setLayout(main_layout)

    def start(self):
        self.search(self.search_edit.text(), -1, -1, 1)

    def next(self):
        row = self.table_widget.currentRow()
        col = self.table_widget.currentColumn() + 1
        if col == self.table_widget.columnCount():
            row += 1
            col = 0
        self.search(self.search_edit.text(), row, col, +1)

    def previous(self):
        row = self.table_widget.currentRow()
        col = self.table_widget.currentColumn() - 1
        if col == -1:
            row -= 1
            col = self.table_widget.columnCount() - 1
        self.search(self.search_edit.text(), row, col, -1)

    def search(self, pattern, row, col, direction):
        nocase = not self.case_button.isChecked()
        word = self.word_button.isChecked()
        regex = self.regex_button.isChecked()
        matches = 0
        index = 0
        if direction > 0:
            row_range = range(self.table_widget.rowCount() - 1, -1, -1)
            col_range = range(self.table_widget.columnCount() - 1, -1, -1)
        else:
            row_range = range(self.table_widget.rowCount())
            col_range = range(self.table_widget.columnCount())
        for i in row_range:
            for j in col_range:
                item = self.table_widget.item(i, j)
                if item is not None:
                    text = item.text()
                    if regex:
                        match = QRegularExpression(pattern).match(
                            text).hasMatch()
                    else:
                        if nocase:
                            text = text.lower()
                            pattern = pattern.lower()
                        if word:
                            match = text == pattern
                        else:
                            match = pattern in text
                    if match and pattern:
                        self.table_widget.item(i, j).setBackground(Qt.yellow)
                        if (direction > 0 and (i > row or i == row and j > col)) or \
                                (direction < 0 and (i < row or i == row and j < col)):
                            self.table_widget.setCurrentCell(i, j)
                            index = matches
                        matches += 1
                    else:
                        self.table_widget.item(i,
                                               j).setBackground(Qt.transparent)
        if pattern:
            self.matches_label.setVisible(True)
            if matches > 0:
                match = matches - index if direction > 0 else index + 1
                self.matches_label.setText(
                    self.tr('match #{}/{}'.format(match, matches)))
                self.matches_label.setStyleSheet('color: #000000')
                modify_font(self.matches_label, bold=True)
            else:
                self.matches_label.setText(self.tr('not found!'))
                self.matches_label.setStyleSheet('color: #FF0000')
                modify_font(self.matches_label, italic=True)
        else:
            self.matches_label.setText('')

    def export(self):
        settings = QSettings()
        filename = QFileDialog.getSaveFileName(self,
                                               self.tr('Export metadata'),
                                               settings.value('save_folder'),
                                               self.tr('CSV files (*.csv)'))[0]
        if not filename:
            return
        if not filename.endswith('.csv'):
            filename += '.csv'
        settings.setValue('save_folder', QFileInfo(filename).absolutePath())

        rows = self.table_widget.rowCount()
        cols = self.table_widget.columnCount()
        table = [[None for _ in range(cols)] for __ in range(rows)]
        for i in range(rows):
            for j in range(cols):
                item = self.table_widget.item(i, j)
                if item is not None:
                    table[i][j] = item.text()
        with open(filename, 'w') as file:
            writer = csv.writer(file)
            writer.writerow(self.table_headers)
            writer.writerows(table)
        self.info_message.emit(self.tr('Table contents exported to disk'))

    def copy(self, item):
        QApplication.clipboard().setText(item.text())
        QToolTip.showText(QCursor.pos(),
                          self.tr('Cell contents copied to clipboard'), self,
                          QRect(), 3000)
示例#9
0
文件: main.py 项目: Yomixe/DNF
class Widget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle("Algorytm DNF")
        """Inicjlizacja zmiennych, na których będą dokynowane obliczenia oraz utworzenie obiektów
        (tabela,pola edycyjne,przyciski)"""
        self.table = QTableWidget()
        self.features = 0
        self.examples = 0
        self.file_name = QLineEdit()
        self.from_file = QPushButton("Wprowadź dane z pliku")
        self.solve = QPushButton("Rozwiąż")
        self.result = QLabel()
        self.error_info = QMessageBox()
        """Tworzenie layoutów a następnie dodawanie do nich widgetów"""
        self.left = QVBoxLayout()
        self.left.addWidget(self.from_file)
        self.left.addWidget(self.solve)
        self.left.addWidget(self.result)
        self.solve.setEnabled(False)
        self.center = QVBoxLayout()
        """Tworzenie  głównego layoutu a następnie dodawanie do nich trzech utworzonych wcześniej"""
        self.layout = QHBoxLayout()
        self.layout.addLayout(self.left)
        self.layout.addLayout(self.center)
        self.setLayout(self.layout)
        """Komunikacja pomiędzy obiektami"""
        self.from_file.clicked.connect(self.create_table)

        self.solve.clicked.connect(self.DNF)

    """Tworzenie tabeli o ilości cech i przykładów podanych przez użytkownika i uzupełnianie jej wartościami z pliku"""

    @Slot()
    def create_table(self):
        try:
            self.file_name.setText(QFileDialog.getOpenFileName()[0])
            with open(self.file_name.text(), 'r') as f:
                for idx_line, line in enumerate(f):
                    self.examples = idx_line
                    for idx, item in enumerate(line.split(' ')):
                        self.features = idx - 1
            self.solve.setEnabled(True)
            self.table.setColumnCount(self.features + 1)
            self.table.setRowCount(self.examples)
            features = list(range(1, self.features + 1))
            features = ["f" + str(x) for x in features]
            self.table.setHorizontalHeaderItem(self.features,
                                               QTableWidgetItem("Etykieta"))
            self.table.setHorizontalHeaderLabels(features)
            self.table.horizontalHeader().setSectionResizeMode(
                QHeaderView.Stretch)
            self.table.verticalHeader().setSectionResizeMode(
                QHeaderView.Stretch)
            self.center.addWidget(self.table)

            with open(self.file_name.text(), 'r') as f:
                for idx_line, line in enumerate(f):
                    for idx, item in enumerate(line.split(' ')):
                        self.table.setItem(idx_line, idx,
                                           QTableWidgetItem(str(item)))

        except FileNotFoundError:
            self.error_info.setWindowTitle("Uwaga!")
            self.error_info.setText("Nie wybrabrano pliku.")
            self.error_info.exec()

    """Konwertowanie obiektowej tabeli na listę D, na której będą dokonywane obliczenia"""

    def convert_to_lists(self):
        self.D = []
        ex = []
        try:
            for i in range(self.table.rowCount()):
                for j in range(self.table.columnCount()):
                    ex.append(int(self.table.item(i, j).text()))
                    if len(ex) == self.table.columnCount():
                        self.D.append(ex)
                        ex = []
                        break

        except:
            self.error_info.setWindowTitle("Uwaga!")
            self.error_info.setText(
                "Uzupełnij poprawnie wszystkie pola w tabeli.")
            self.error_info.exec()

    """Algorytm DNF"""

    @Slot()
    def DNF(self):
        self.convert_to_lists()
        P = [self.D[i] for i in range(len(self.D)) if self.D[i][-1] == 1]
        h = []
        fail = 0
        while P != [[-1] * len(P[i]) for i in range(len(P))] and fail == 0:
            N = [self.D[i] for i in range(len(self.D)) if self.D[i][-1] == 0]
            r = []
            while N != [[-1] * len(N[i]) for i in range(len(N))] and fail == 0:
                chosen_index = self.find_f(P, N)
                r.append(chosen_index)
                self.clear_negative_rows(chosen_index, N)
                if len(r) != len(set(r)):
                    fail = 1
            if self.clear_positive_rows(r, P) == 1:
                fail = 1
            r = ["f" + str(i + 1) for i in r]
            r = " ʌ ".join(r)
            h.append(r)
        self.get_solution(h, fail)

    def find_f(self, P, N):
        sum_p = list(self.sum_over_columns(P))
        sum_n = list(self.sum_over_columns(N))
        v = 0
        chosen_index = 0
        for i in range(len(sum_p)):
            if sum_n[i] == 0:
                sum_n[i] = 0.001
            if sum_p[i] // sum_n[i] > v:
                v = sum_p[i] // sum_n[i]
                chosen_index = i
        return chosen_index

    def sum_over_columns(self, tab):
        for i in range(len(tab[0]) - 1):
            count = 0
            for j in range(len(tab)):
                if tab[j][i] == 1:
                    count += 1
            yield count

    def clear_negative_rows(self, index, N):
        n = len(N)
        for i in range(n):
            if N[i][index] == 0:
                N[i] = [-1] * len(N[i])

    def clear_positive_rows(self, r, P):
        n = len(P)
        mark = 0
        for i in range(n):
            sum = 0
            for j in r:
                if P[i][j] == 1:
                    sum += 1
            if sum == len(r):
                P[i] = [-1] * len(P[i])
                mark += 1
        if mark == 0:
            return 1
        return 0

    def get_solution(self, h, fail):
        if fail == 1:
            self.result.setText("Brak rozwiązania")
        else:
            self.result.setText("Rozwiązanie:\n\nh= (" + ") v (".join(h) + ")")
示例#10
0
class UiMainWindow(object):
    '''Интерфейс основного окна программы.
    Created by: Qt User Interface Compiler.
    Задано:
        панель инструментов с кнопками "Новый расчёт" (очистка всех полей),
        выбор режима расчёта, запуск расчёта;

        четыре поля ввода (длина заготовки, длина безусловного отхода,
        ширина реза, длина первичной обрезки торца заготовки)

        таблица ввода длин элементов и их количеств;

        кнопки "добавить строку в конец таблицы" и "удалить последнюю строку
        в таблице";

        поле вывода результата расчёта.
    '''
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(700, 495)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.main_frame = QFrame(self.centralwidget)
        self.main_frame.setObjectName(u"main_frame")
        self.main_frame.setFrameShape(QFrame.StyledPanel)
        self.main_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_2 = QVBoxLayout(self.main_frame)
        self.verticalLayout_2.setSpacing(0)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)

        # "панель инструментов"
        self.top_frame = QFrame(self.main_frame)
        self.top_frame.setObjectName(u"top_frame")
        self.top_frame.setMinimumSize(QSize(0, 60))
        self.top_frame.setMaximumSize(QSize(16777215, 60))
        self.top_frame.setFrameShape(QFrame.StyledPanel)
        self.top_frame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout = QHBoxLayout(self.top_frame)
        self.horizontalLayout.setSpacing(5)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(5, 5, 5, 5)

        # кнопка "новый расчёт"
        self.new_calc_btn = QPushButton(self.top_frame)
        self.new_calc_btn.setObjectName(u"new_calc_btn")
        self.new_calc_btn.setMinimumSize(QSize(110, 50))
        self.new_calc_btn.setMaximumSize(QSize(110, 50))
        icon = QIcon()
        icon.addFile(NEW_CALC_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.new_calc_btn.setIcon(icon)
        self.new_calc_btn.setIconSize(QSize(45, 45))

        self.horizontalLayout.addWidget(self.new_calc_btn)

        # кнопка "выбор режима расчёта"
        self.select_mode_btn = QPushButton(self.top_frame)
        self.select_mode_btn.setObjectName(u"select_mode_btn")
        self.select_mode_btn.setMinimumSize(QSize(110, 50))
        self.select_mode_btn.setMaximumSize(QSize(110, 50))
        icon1 = QIcon()
        icon1.addFile(SET_MODE_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.select_mode_btn.setIcon(icon1)
        self.select_mode_btn.setIconSize(QSize(45, 45))

        self.horizontalLayout.addWidget(self.select_mode_btn)

        # кнопка "запуск расчёта"
        self.start_calc_btn = QPushButton(self.top_frame)
        self.start_calc_btn.setObjectName(u"start_calc_btn")
        self.start_calc_btn.setMinimumSize(QSize(110, 50))
        self.start_calc_btn.setMaximumSize(QSize(110, 50))
        icon2 = QIcon()
        icon2.addFile(START_CALC_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.start_calc_btn.setIcon(icon2)
        self.start_calc_btn.setIconSize(QSize(45, 45))

        self.horizontalLayout.addWidget(self.start_calc_btn)

        self.horizontalSpacer = QSpacerItem(338, 20, QSizePolicy.Expanding,
                                            QSizePolicy.Minimum)

        self.horizontalLayout.addItem(self.horizontalSpacer)

        self.verticalLayout_2.addWidget(self.top_frame)

        self.bottom_frame = QFrame(self.main_frame)
        self.bottom_frame.setObjectName(u"bottom_frame")
        self.bottom_frame.setFrameShape(QFrame.StyledPanel)
        self.bottom_frame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_2 = QHBoxLayout(self.bottom_frame)
        self.horizontalLayout_2.setSpacing(5)
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
        self.horizontalLayout_2.setContentsMargins(5, 5, 5, 5)
        self.input_frame = QFrame(self.bottom_frame)
        self.input_frame.setObjectName(u"input_frame")
        self.input_frame.setMinimumSize(QSize(340, 0))
        self.input_frame.setMaximumSize(QSize(340, 16777215))
        self.input_frame.setFrameShape(QFrame.StyledPanel)
        self.input_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_3 = QVBoxLayout(self.input_frame)
        self.verticalLayout_3.setSpacing(5)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)

        # поле ввода длины заготовки
        self.length_layout = QHBoxLayout()
        self.length_layout.setSpacing(5)
        self.length_layout.setObjectName(u"length_layout")
        self.length_label = QLabel(self.input_frame)
        self.length_label.setObjectName(u"length_label")
        self.length_label.setMinimumSize(QSize(165, 25))
        self.length_label.setMaximumSize(QSize(165, 25))
        self.length_layout.addWidget(self.length_label)
        self.length_entry = QLineEdit(self.input_frame)
        self.length_entry.setObjectName(u"length_entry")
        self.length_entry.setMinimumSize(QSize(165, 25))
        self.length_entry.setMaximumSize(QSize(165, 25))
        self.length_layout.addWidget(self.length_entry)
        self.verticalLayout_3.addLayout(self.length_layout)

        # поле ввода длины безусловного отхода
        self.waste_layout = QHBoxLayout()
        self.waste_layout.setSpacing(5)
        self.waste_layout.setObjectName(u"waste_layout")
        self.waste_label = QLabel(self.input_frame)
        self.waste_label.setObjectName(u"waste_label")
        self.waste_label.setMinimumSize(QSize(165, 25))
        self.waste_label.setMaximumSize(QSize(165, 25))
        self.waste_layout.addWidget(self.waste_label)
        self.waste_entry = QLineEdit(self.input_frame)
        self.waste_entry.setObjectName(u"waste_entry")
        self.waste_entry.setMinimumSize(QSize(165, 25))
        self.waste_entry.setMaximumSize(QSize(165, 25))
        self.waste_layout.addWidget(self.waste_entry)
        self.verticalLayout_3.addLayout(self.waste_layout)

        # поле ввода ширины реза
        self.cut_layout = QHBoxLayout()
        self.cut_layout.setSpacing(5)
        self.cut_layout.setObjectName(u"cut_layout")
        self.cut_label = QLabel(self.input_frame)
        self.cut_label.setObjectName(u"cut_label")
        self.cut_label.setMinimumSize(QSize(165, 25))
        self.cut_label.setMaximumSize(QSize(165, 25))
        self.cut_layout.addWidget(self.cut_label)
        self.cut_entry = QLineEdit(self.input_frame)
        self.cut_entry.setObjectName(u"cut_entry")
        self.cut_entry.setMinimumSize(QSize(165, 25))
        self.cut_entry.setMaximumSize(QSize(165, 25))
        self.cut_layout.addWidget(self.cut_entry)
        self.verticalLayout_3.addLayout(self.cut_layout)

        # поле ввода длины подрезки торца заготовки
        self.trim_layout = QHBoxLayout()
        self.trim_layout.setSpacing(5)
        self.trim_layout.setObjectName(u"trim_layout")
        self.trim_label = QLabel(self.input_frame)
        self.trim_label.setObjectName(u"trim_label")
        self.trim_label.setMinimumSize(QSize(165, 25))
        self.trim_label.setMaximumSize(QSize(165, 25))
        self.trim_layout.addWidget(self.trim_label)
        self.trim_entry = QLineEdit(self.input_frame)
        self.trim_entry.setObjectName(u"trim_entry")
        self.trim_entry.setMinimumSize(QSize(165, 25))
        self.trim_entry.setMaximumSize(QSize(165, 25))
        self.trim_layout.addWidget(self.trim_entry)
        self.verticalLayout_3.addLayout(self.trim_layout)

        # таблица ввода длин и количеств элементов
        self.input_table = QTableWidget(self.input_frame)
        if (self.input_table.columnCount() < 2):
            self.input_table.setColumnCount(2)
        if (self.input_table.rowCount() < 7):
            self.input_table.setRowCount(7)
        self.input_table.setObjectName(u"input_table")
        self.input_table.setRowCount(7)
        self.input_table.setColumnCount(2)
        self.input_table.horizontalHeader().setMinimumSectionSize(33)
        self.input_table.horizontalHeader().setDefaultSectionSize(130)
        self.input_table.horizontalHeader().setProperty(
            "showSortIndicator",
            True,
        )
        self.input_table.horizontalHeader().setStretchLastSection(True)
        self.input_table.verticalHeader().setMinimumSectionSize(30)
        self.input_table.verticalHeader().setDefaultSectionSize(30)
        self.verticalLayout_3.addWidget(self.input_table)

        self.horizontalLayout_3 = QHBoxLayout()
        self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")

        # кнопка "добавить строку в конец таблицы"
        self.add_str_button = QPushButton(self.input_frame)
        self.add_str_button.setObjectName(u"add_str_button")
        self.add_str_button.setMinimumSize(QSize(150, 35))
        self.add_str_button.setMaximumSize(QSize(150, 35))
        icon3 = QIcon()
        icon3.addFile(
            ADD_STR_ICON,
            QSize(),
            QIcon.Normal,
            QIcon.Off,
        )
        self.add_str_button.setIcon(icon3)
        self.add_str_button.setIconSize(QSize(25, 25))
        self.horizontalLayout_3.addWidget(self.add_str_button)

        # кнопка "удалить последнюю строку в таблице"
        self.remove_str_button = QPushButton(self.input_frame)
        self.remove_str_button.setObjectName(u"remove_str_button")
        self.remove_str_button.setMinimumSize(QSize(150, 35))
        self.remove_str_button.setMaximumSize(QSize(150, 35))
        icon4 = QIcon()
        icon4.addFile(
            DESTR_STR_ICON,
            QSize(),
            QIcon.Normal,
            QIcon.Off,
        )
        self.remove_str_button.setIcon(icon4)
        self.remove_str_button.setIconSize(QSize(25, 25))
        self.horizontalLayout_3.addWidget(self.remove_str_button)

        self.verticalLayout_3.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_2.addWidget(self.input_frame)

        self.output_frame = QFrame(self.bottom_frame)
        self.output_frame.setObjectName(u"output_frame")
        self.output_frame.setFrameShape(QFrame.StyledPanel)
        self.output_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_4 = QVBoxLayout(self.output_frame)
        self.verticalLayout_4.setObjectName(u"verticalLayout_4")

        # поле вывода результатов расчёта
        self.textBrowser = QTextBrowser(self.output_frame)
        self.textBrowser.setObjectName(u"textBrowser")
        self.verticalLayout_4.addWidget(self.textBrowser)

        self.horizontalLayout_4 = QHBoxLayout()
        self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")

        # строка состояния
        self.label_2 = QLabel(self.output_frame)
        self.label_2.setObjectName(u"label_2")
        self.label_2.setMinimumSize(QSize(25, 25))
        self.label_2.setMaximumSize(QSize(16777215, 25))
        self.horizontalLayout_4.addWidget(self.label_2)
        self.horizontalSpacer_2 = QSpacerItem(
            40,
            20,
            QSizePolicy.Expanding,
            QSizePolicy.Minimum,
        )

        self.horizontalLayout_4.addItem(self.horizontalSpacer_2)

        # поле вывода версии программы
        self.label = QLabel(self.output_frame)
        self.label.setObjectName(u"label")
        self.label.setMinimumSize(QSize(0, 25))
        self.label.setMaximumSize(QSize(16777215, 25))

        self.horizontalLayout_4.addWidget(self.label)
        self.verticalLayout_4.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_2.addWidget(self.output_frame)
        self.verticalLayout_2.addWidget(self.bottom_frame)
        self.verticalLayout.addWidget(self.main_frame)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
# setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(
            QCoreApplication.translate("MainWindow", u"simple linear nesting",
                                       None))
        # if QT_CONFIG(tooltip)
        self.new_calc_btn.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Clear all fields, Ctrl+N", None))
        # endif // QT_CONFIG(tooltip)
        self.new_calc_btn.setText(
            QCoreApplication.translate("MainWindow", u"new", None))
        # if QT_CONFIG(shortcut)
        self.new_calc_btn.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+N", None))
        # endif // QT_CONFIG(shortcut)
        # if QT_CONFIG(tooltip)
        self.select_mode_btn.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Select calculation mode, Ctrl+M",
                                       None))
        # endif // QT_CONFIG(tooltip)
        self.select_mode_btn.setText(
            QCoreApplication.translate("MainWindow", u"mode", None))
        # if QT_CONFIG(shortcut)
        self.select_mode_btn.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+M", None))
        # endif // QT_CONFIG(shortcut)
        # if QT_CONFIG(tooltip)
        self.start_calc_btn.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Start calculation, Ctrl+R", None))
        # endif // QT_CONFIG(tooltip)
        self.start_calc_btn.setText(
            QCoreApplication.translate("MainWindow", u"start", None))
        # if QT_CONFIG(shortcut)
        self.start_calc_btn.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+R", None))
        # endif // QT_CONFIG(shortcut)
        self.length_label.setText(
            QCoreApplication.translate("MainWindow", u"workpiece length",
                                       None))
        # if QT_CONFIG(tooltip)
        self.length_entry.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Enter the length of the workpiece",
                                       None))
        # endif // QT_CONFIG(tooltip)
        self.waste_label.setText(
            QCoreApplication.translate("MainWindow", u"irreducible waste",
                                       None))
        # if QT_CONFIG(tooltip)
        self.waste_entry.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Enter the length of the waste", None))
        # endif // QT_CONFIG(tooltip)
        self.cut_label.setText(
            QCoreApplication.translate("MainWindow", u"cutting width", None))
        # if QT_CONFIG(tooltip)
        self.cut_entry.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Enter the width of the cutting",
                                       None))
        # endif // QT_CONFIG(tooltip)
        self.trim_label.setText(
            QCoreApplication.translate("MainWindow", u"trim the end", None))
        # if QT_CONFIG(tooltip)
        self.trim_entry.setToolTip(
            QCoreApplication.translate(
                "MainWindow", u"Enter the length of the trimming end", None))
        # endif // QT_CONFIG(tooltip)
        # if QT_CONFIG(tooltip)
        self.add_str_button.setToolTip(
            QCoreApplication.translate(
                "MainWindow", u"Add another row to the table, Ctrl++", None))
        # endif // QT_CONFIG(tooltip)
        self.add_str_button.setText("")
        # if QT_CONFIG(shortcut)
        self.add_str_button.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl++", None))
        # endif // QT_CONFIG(shortcut)
        # if QT_CONFIG(tooltip)
        self.remove_str_button.setToolTip(
            QCoreApplication.translate(
                "MainWindow", u"Delete the last row in the table, Ctrl+-",
                None))
        # endif // QT_CONFIG(tooltip)
        self.remove_str_button.setText("")
        # if QT_CONFIG(shortcut)
        self.remove_str_button.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+-", None))
        # endif // QT_CONFIG(shortcut)
        self.label_2.setText("")
        self.label.setText(
            QCoreApplication.translate("MainWindow", u"v.0.0.0", None))
示例#11
0
class ConfigurationDialog(QDialog):
    def __init__(self, node):
        super().__init__()

        self.node = node

        self.delete_popup = None

        self.layout = QGridLayout()

        self.table = QTableWidget(0, 2)
        self.node.configuration.parameter_change.connect(
            self.handle_configuration_change)

        self.table.cellChanged.connect(self.handle_cell_change)
        self.table.setHorizontalHeaderLabels(['Key', 'Value'])

        self.layout.addWidget(self.table, 0, 0, 1, 2)

        self.deleteButton = QPushButton('Remove Selected Row')
        self.deleteButton.clicked.connect(self.handle_delete_action)
        self.layout.addWidget(self.deleteButton, 1, 0)

        self.addButton = QPushButton('Add Configuration')
        self.addButton.clicked.connect(self.handle_add_action)
        self.layout.addWidget(self.addButton, 1, 1)

        self.setLayout(self.layout)

    #################################
    # Add/Update/Get for table rows #
    #################################

    def add_row(self, key, value):
        """
        Adds a new row with key and value.

        :param key: Key for the new row
        :param value: Value for the new row
        :return: None
        """

        row_index = self.table.rowCount()
        self.table.insertRow(row_index)
        self.update_row(row_index, key, value)

    def update_row(self, row_index, key, value):
        """
        Updates a table row by index, with key and value.

        :param row_index: Index of the row to be updated
        :param key: Key for that row
        :param value: Value for that row
        :return: None
        """

        # Disconnecting cellChanged event so we don't get a feedback loop
        self.table.cellChanged.disconnect()

        for column_index, cell_text in enumerate([key, value]):
            item = QTableWidgetItem()
            item.setText(str(cell_text))

            if column_index != 1:
                # noinspection PyUnresolvedReferences
                item.setFlags(Qt.ItemIsEnabled)

            self.table.setItem(row_index, column_index, item)

        # Connecting the cellChanged event again
        self.table.cellChanged.connect(self.handle_cell_change)

        self.table.resizeColumnsToContents()

    def remove_row(self, row_index):
        row: Row = self.get_row_by_index(row_index)
        key = row[1][0]
        value = row[1][1]

        old_values = self.node.configuration[key]
        if old_values is None:
            old_values = []
        elif not isinstance(old_values, list):
            old_values = [old_values]

        new_values = []
        for old_value in old_values:
            if str(old_value) != str(value):
                new_values.append(old_value)

        if key in self.node.configuration:
            del self.node.configuration[key]

        self.node.configuration[key] = new_values

        # The event triggered by configuration values changing will update the table

    def get_rows_by_key(self, key: str) -> List[Row]:
        """
        Returns the list of rows for a specific key. Since we can have multiple values for the same key
        we need to return a list of rows.

        :param key: The key we're looking for
        :return: The list of rows in the format:
        [
            (row_index, [column0value, column1value, ...]),
            ...
        ]
        """

        rows = []
        for row_index in range(self.table.rowCount()):
            _key = self.table.item(row_index, 0).text() if self.table.item(
                row_index, 0) else ''
            if _key == key:
                rows.append((row_index, [
                    self.table.item(row_index, column_index).text()
                    if self.table.item(row_index, column_index) else ''
                    for column_index in range(self.table.columnCount())
                ]))

        return rows

    def get_row_by_index(self, index: int) -> Optional[Row]:
        """
        Returns a row by its index, or None if it doesn't exist.

        :param index: index of the row to retrieve
        :return: If the row doesn't exist, returns None
        If the row exists, returns a tuple with the row number and the list of columns
        Example: (1, ['server', '1'])
        """

        for row_index in range(self.table.rowCount()):
            if row_index == index:
                return (row_index, [
                    self.table.item(row_index, column_index).text()
                    if self.table.item(row_index, column_index) else ''
                    for column_index in range(self.table.columnCount())
                ])

        return None

    ##################
    # Event Handlers #
    ##################

    def handle_configuration_change(self, _: str, key: str, values: List[str]):
        """
        Handles the event of a configuration change and updates the table.
        There's a complication here because a single key can have multiple values, for parameters like
        'addnode' or 'connect' on bitcoind. So we need to handle them all.

        :param _: The name of the node. (bitcoind, lnd, tor). Unused here.
        :param key: Which key was updated
        :param values: All values for that key.
        :return: None
        """

        if not isinstance(values, list):
            values = [values]

        # Deleting extra existing rows
        old_rows: List[Row] = self.get_rows_by_key(key)
        delete_rows_count = len(old_rows) - len(values)
        if delete_rows_count > 0:
            # In this case there's more rows in the table than should exist
            for old_row in reversed(old_rows):
                if delete_rows_count == 0:
                    break

                self.table.removeRow(old_row[0])
                delete_rows_count -= 1

        # Adding new rows
        add_rows_count = len(values) - len(old_rows)
        if add_rows_count > 0:
            # In this case there's less rows in the table than should exist
            for i in range(add_rows_count):
                new_value = values[len(old_rows) + i]
                self.add_row(key, new_value)

        # Updating rows
        update_values = values[0:min(len(values), len(old_rows))]
        for old_row_index, update_value in enumerate(update_values):
            row_index = old_rows[old_row_index][0]
            self.update_row(row_index, key, update_value)

    def handle_cell_change(self, row_index: int, column_index: int):
        """
        Handles the event of a cell value change in the UI.
        Updates the configuration assuming that it is valid.
        Otherwise just keeps what was there before

        :param row_index: Index of the row that changed
        :param column_index: Index of the column that changed
        :return: None
        """

        if column_index == 0:
            row: Row = self.get_row_by_index(row_index)
            key = row[1][0]
            if key == '':
                self.table.removeRow(row_index)
        elif column_index == 1:
            row: Row = self.get_row_by_index(row_index)
            new_value = row[1][1]
            key = row[1][0]

            rows = self.get_rows_by_key(key)
            new_values = sorted([row[1][1] for row in rows])

            old_values = self.node.configuration[key]
            if old_values is None:
                old_values = []
            elif not isinstance(old_values, list):
                old_values = [old_values]

            old_values.sort()

            if [str(e) for e in old_values] != [str(e) for e in new_values]:
                is_valid = self.node.configuration.is_valid_configuration(
                    key, new_value) and key != ''
                if is_valid:
                    if key in self.node.configuration:
                        del self.node.configuration[key]
                    self.node.configuration[key] = new_values
                else:
                    if key == '':
                        self.table.removeRow(row_index)
                    else:
                        for old_value in old_values:
                            if old_value not in new_values:
                                self.update_row(row_index, key, old_value)
                                break

    def handle_confirm_deletion(self):
        self.node.configuration.parameter_change.disconnect()

        items = list(self.table.selectedItems())

        for i, item in enumerate(items):
            if i == len(items) - 1:
                self.node.configuration.parameter_change.connect(
                    self.handle_configuration_change)
            self.remove_row(item.row())

        self.delete_popup = None

    def handle_delete_action(self):
        keys = []
        for item in list(self.table.selectedItems()):
            row: Row = self.get_row_by_index(item.row())
            keys.append(row[1][0])

        if keys:
            self.delete_popup = QMessageBox()
            self.delete_popup.setWindowTitle('Confirm deletion')
            self.delete_popup.setText('Are you sure you want to delete ' +
                                      ', '.join(keys) + '?')
            self.delete_popup.show()
            self.delete_popup.buttonClicked.connect(
                self.handle_confirm_deletion)

    def handle_add_action(self):
        row_index = self.table.rowCount()
        self.table.insertRow(row_index)
class ExtraWindow(QtWidgets.QDialog):
    def __init__(self, parent):
        super().__init__(parent)

        self.setWindowTitle("customer - Table")
        self.setWindowIcon(QtGui.QIcon("assets/img/icons8-edit-file-64.png"))

        self.resize(662, 438)
        self.save_talble_changes = QPushButton("Save table changes", self)
        self.save_talble_changes.setGeometry(390, 290, 251, 31)

        self.add_table_main = QPushButton("Add Column ", self)
        self.add_table_main.setGeometry(390, 260, 251, 28)
        #self.add_table_main.clicked.connect(self.add_column)

        self.delet_table_column = QPushButton("Delet table column", self)
        self.delet_table_column.setGeometry(390, 330, 251, 31)

        self.not_null_box = QCheckBox("Not Null", self)
        self.not_null_box.setGeometry(220, 330, 81, 61)

        self.colm_name_label = QLabel("Column Name:", self)
        self.colm_name_label.setGeometry(10, 250, 111, 41)

        self.table_name_label_2 = QLabel("Table Name", self)
        self.table_name_label_2.setGeometry(10, 10, 91, 21)

        self.comn_name_line_edit = QLineEdit(self)
        self.comn_name_line_edit.setGeometry(110, 260, 151, 22)

        self.data_type_label = QLabel("Data Type", self)
        self.data_type_label.setGeometry(10, 300, 61, 16)

        self.data_type_line_edit = QLineEdit(self)
        self.data_type_line_edit.setGeometry(110, 300, 151, 22)

        self.table_name_line_edit = QLineEdit(self)
        self.table_name_line_edit.setGeometry(110, 10, 391, 22)

        self.foreign_key_box = QCheckBox("Foreign Key", self)
        self.foreign_key_box.setGeometry(120, 330, 91, 61)

        self.primary_key_box = QCheckBox("Primary Key", self)
        self.primary_key_box.setGeometry(20, 330, 111, 61)

        self.table_widget = QTableWidget(self)

        if (self.table_widget.columnCount() < 6):
            self.table_widget.setColumnCount(6)

        __qtablewidgetitem = QTableWidgetItem()
        self.table_widget.setHorizontalHeaderItem(0, __qtablewidgetitem)
        __qtablewidgetitem1 = QTableWidgetItem()
        self.table_widget.setHorizontalHeaderItem(1, __qtablewidgetitem1)
        __qtablewidgetitem2 = QTableWidgetItem()
        self.table_widget.setHorizontalHeaderItem(2, __qtablewidgetitem2)
        __qtablewidgetitem3 = QTableWidgetItem()
        self.table_widget.setHorizontalHeaderItem(3, __qtablewidgetitem3)
        __qtablewidgetitem4 = QTableWidgetItem()
        self.table_widget.setHorizontalHeaderItem(4, __qtablewidgetitem4)
        __qtablewidgetitem5 = QTableWidgetItem()
        self.table_widget.setHorizontalHeaderItem(5, __qtablewidgetitem5)

        self.table_widget.setGeometry(0, 40, 661, 201)
        self.table_widget.setColumnWidth(2, 85)
        self.table_widget.setColumnWidth(3, 85)
        self.table_widget.setColumnWidth(4, 85)

        self.frame = QFrame(self)
        self.frame.setGeometry(0, 390, 661, 51)
        self.frame.setStyleSheet(u"background-color: rgb(45,45,45);")
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setFrameShadow(QFrame.Raised)

        self.cancel_button = QPushButton("Cancel button", self.frame)
        self.cancel_button.setGeometry(550, 10, 111, 28)

        self.cancel_button.setStyleSheet(
            u"background-color: rgb(255,255,255);")
        self.add_table_button = QPushButton("Add table", self.frame)

        self.add_table_button.setGeometry(442, 10, 101, 28)
        self.add_table_button.setStyleSheet(
            u"background-color: rgb(255,255,255);")

        self.tables()

        self.show()

    def tables(self):
        '''
        self.setWindowTitle(QCoreApplication.translate("ExtraWindow", u"Dialog", None))
        self.save_talble_changes.setText(QCoreApplication.translate("ExtraWindow", u"Save Table Changes", None))
        self.add_table_main.setText(QCoreApplication.translate("ExtraWindow", u"Add Table", None))
        self.delet_table_column.setText(QCoreApplication.translate("ExtraWindow", u"Delete Table Column", None))
        self.not_null_box.setText(QCoreApplication.translate("ExtraWindow", u"Not null", None))
        self.colm_name_label.setText(QCoreApplication.translate("ExtraWindow", u"Colomn Name", None))
        self.table_name_label_2.setText(QCoreApplication.translate("ExtraWindow", u"Table Name", None))
        self.data_type_label.setText(QCoreApplication.translate("ExtraWindow", u"Data Type", None))
        self.foreign_key_box.setText(QCoreApplication.translate("ExtraWindow", u"Foreign key", None))
        self.primary_key_box.setText(QCoreApplication.translate("ExtraWindow", u"Primary key", None))
        '''
        ___qtablewidgetitem = self.table_widget.horizontalHeaderItem(0)
        ___qtablewidgetitem.setText(
            QCoreApplication.translate("ExtraWindow", u"Column Name", None))
        ___qtablewidgetitem1 = self.table_widget.horizontalHeaderItem(1)
        ___qtablewidgetitem1.setText(
            QCoreApplication.translate("ExtraWindow", u"Data Type", None))
        ___qtablewidgetitem2 = self.table_widget.horizontalHeaderItem(2)
        ___qtablewidgetitem2.setText(
            QCoreApplication.translate("ExtraWindow", u"Primary key", None))
        ___qtablewidgetitem3 = self.table_widget.horizontalHeaderItem(3)
        ___qtablewidgetitem3.setText(
            QCoreApplication.translate("ExtraWindow", u"Foreign key", None))
        ___qtablewidgetitem4 = self.table_widget.horizontalHeaderItem(4)
        ___qtablewidgetitem4.setText(
            QCoreApplication.translate("ExtraWindow", u"Not Null", None))
        ___qtablewidgetitem5 = self.table_widget.horizontalHeaderItem(5)
        ___qtablewidgetitem5.setText(
            QCoreApplication.translate("ExtraWindow", u"Default", None))
        '''