コード例 #1
0
class LocalButtonsConf(OptionsDialogGroupBox):
    def __init__(self, name, main):
        self.main = main
        OptionsDialogGroupBox.__init__(self, name, main)
        self.buttonBox = QGroupBox("Pins")
        self.buttonBoxLayout = QVBoxLayout()
        self.buttonBox.setLayout(self.buttonBoxLayout)

    def initUI(self):
        vbox = QVBoxLayout()
        self.polBox = QCheckBox("Invert")
        vbox.addWidget(self.polBox)
        self.buttongroup = QButtonGroup()
        self.buttongroup.setExclusive(False)
        vbox.addWidget(self.buttonBox)

        self.setLayout(vbox)

    def initButtons(self, num):
        #delete buttons
        self.num = num

        # Remove buttons
        for i in range(self.buttonBoxLayout.count()):
            b = self.buttonBoxLayout.takeAt(0)
            self.buttonBoxLayout.removeItem(b)
            b.widget().deleteLater()
        for b in self.buttongroup.buttons():
            self.buttongroup.removeButton(b)

        self.buttonBox.update()

        for i in range(self.num):
            cb = QCheckBox(str(i + 1))
            self.buttongroup.addButton(cb, i)
            self.buttonBoxLayout.addWidget(cb)

        def localcb(mask):
            for i in range(self.num):
                self.buttongroup.button(i).setChecked(mask & (1 << i))

        self.main.comms.serialGetAsync("local_btnmask?", localcb, int)

    def apply(self):
        mask = 0
        for i in range(self.num):
            if (self.buttongroup.button(i).isChecked()):
                mask |= 1 << i
        self.main.comms.serialWrite("local_btnmask=" + str(mask))
        self.main.comms.serialWrite("local_btnpol=" +
                                    ("1" if self.polBox.isChecked() else "0"))

    def readValues(self):
        self.main.comms.serialGetAsync("local_btnpins?", self.initButtons, int)

        self.main.comms.serialGetAsync("local_btnpol?", self.polBox.setChecked,
                                       int)
コード例 #2
0
class AnalogInputConf(OptionsDialogGroupBox):
    analogbtns = QButtonGroup()
    axes = 0

    def __init__(self, name, main):
        self.main = main
        OptionsDialogGroupBox.__init__(self, name, main)
        self.analogbtns.setExclusive(False)
        self.buttonBox = QGroupBox("Pins")
        self.buttonBoxLayout = QVBoxLayout()
        self.buttonBox.setLayout(self.buttonBoxLayout)

    def initUI(self):
        layout = QVBoxLayout()
        self.autorangeBox = QCheckBox("Autorange")
        layout.addWidget(self.autorangeBox)
        layout.addWidget(self.buttonBox)
        self.setLayout(layout)

    def readValues(self):
        self.main.comms.serialGetAsync("local_ain_num?", self.createAinButtons,
                                       int)
        self.main.comms.serialGetAsync("local_ain_acal?",
                                       self.autorangeBox.setChecked, int)

    def createAinButtons(self, axes):
        self.axes = axes

        # remove buttons
        for i in range(self.buttonBoxLayout.count()):
            b = self.buttonBoxLayout.takeAt(0)
            self.buttonBoxLayout.removeItem(b)
            b.widget().deleteLater()
        for b in self.analogbtns.buttons():
            self.analogbtns.removeButton(b)

        # add buttons
        for i in range(axes):
            btn = QCheckBox(str(i + 1), self)
            self.analogbtns.addButton(btn, i)
            self.buttonBoxLayout.addWidget(btn)

        def f(axismask):
            for i in range(self.axes):
                self.analogbtns.button(i).setChecked(axismask & (1 << i))

        self.main.comms.serialGetAsync("local_ain_mask?", f, int)

    def apply(self):
        mask = 0
        for i in range(self.axes):
            if (self.analogbtns.button(i).isChecked()):
                mask |= 1 << i
        self.main.comms.serialWrite("local_ain_mask=" + str(mask))
        self.main.comms.serialWrite("local_ain_acal=" + (
            "1" if self.autorangeBox.isChecked() else "0"))
コード例 #3
0
ファイル: QScrollableBox.py プロジェクト: lihaochen910/Candy
class QScrollableBox(QWidget):
    def __init__(self, parent):
        super(QScrollableBox, self).__init__(parent)
        mainLayout = QVBoxLayout()
        mainLayout.setContentsMargins(0, 0, 0, 0)
        self.scrollArea = QScrollArea(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        self.scrollArea.setSizePolicy(sizePolicy)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.scrollArea.setWidgetResizable(True)

        mainLayout.addWidget(self.scrollArea)
        self.setLayout(mainLayout)
        scrollContents = QWidget()
        self.m_layout = QVBoxLayout()
        self.m_layout.setContentsMargins(0, 0, 0, 0)
        self.m_layout.setSizeConstraint(QLayout.SetNoConstraint)
        scrollContents.setLayout(self.m_layout)

        self.scrollArea.setWidget(scrollContents)

    def addWidget(self, w):
        if not w:
            return
        count = self.m_layout.count()
        if count > 1:
            self.m_layout.removeItem(self.m_layout.itemAt(count - 1))
        self.m_layout.addWidget(w)
        w.show()
        self.m_layout.addStretch()
        self.scrollArea.update()

    def removeWidget(self, w):
        self.m_layout.removeWidget(w)
        self.scrollArea.update()

    def insertWidget(self, i, w):
        self.m_layout.insertWidget(i, w)
        self.scrollArea.update()

    def clearWidgets(self):
        item = self.m_layout.takeAt(0)
        while item != None:
            item.widget().deleteLater()
            self.m_layout.removeItem(item)
            del item

        self.scrollArea.update()

    def indexOf(self, w):
        return self.m_layout.indexOf(w)
コード例 #4
0
class StateGrid(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.central_widget = QWidget(self)
        self.scroll_area = QScrollArea(self)
        self.vbox = QVBoxLayout(self)
        self.rows = []
        self.new_row()
        self.init_grid()

    def new_row(self):
        size = len(self.vbox)
        hbox = QHBoxLayout(self)
        self.vbox.addLayout(hbox, 1)
        if len(self.vbox) == size:
            hbox = QHBoxLayout(self)
            self.vbox.addLayout(hbox, 1)
        self.rows.append(hbox)

    def add_number(self, number_color):
        number, color = number_color
        if len(self.rows) == 0 or len(self.rows[-1]) >= 7:
            self.new_row()
        new_number = Number(self.scroll_area, number, color)
        new_number.number_clicked_signal.connect(self.on_number_clicked)
        self.rows[-1].addWidget(new_number)

    def pop_number(self):
        item = self.rows[-1].itemAt(len(self.rows[-1]) - 1)
        number = item.widget()
        self.rows[-1].removeItem(item)
        number.hide()
        number.deleteLater()
        if len(self.rows[-1]) == 0:
            self.vbox.removeItem(self.rows[-1])
            self.rows.pop()

    def init_grid(self):
        self.setFixedSize(400 * variables.SCALE, 500 * variables.SCALE)
        self.scroll_area.setFixedSize(400 * variables.SCALE,
                                      500 * variables.SCALE)
        self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.central_widget.setLayout(self.vbox)
        self.scroll_area.setWidget(self.central_widget)
        self.scroll_area.setWidgetResizable(True)

    def on_number_clicked(self, number):
        variables.GAME_INTERFACE.click_number(number)
コード例 #5
0
    def layout_group(self, name: str, vlayout: QVBoxLayout,
                     hlayouts: typing.List[QHBoxLayout],
                     path_variables: typing.List[Variable],
                     widgets: typing.List[QLineEdit],
                     button_fn: typing.Callable[[Variable, str],
                                                type(None)]):
        """
        Layout the controls in one of the groups: input precomputed,
        output precomputed or tiffs

        :param name: A display name for the label to the left of the line edit
        :param vlayout: The top-level QT layout
        :param hlayouts: A list of the subsidiary horizontal layouts per channel
        :param path_variables: path variables per channel
        :param widgets: the QLineEdit widgets per channel
        :param button_fn: The function to run when someone presses the widget's
                          path-finding button.
        """
        n_channels = self.model.n_alignment_channels.get()
        while len(hlayouts) > n_channels:
            idx = len(hlayouts) - 1
            path_variables[idx].unregister_callback("apply-alignment")
            hlayout = hlayouts[idx]
            while hlayout.count() > 0:
                item = hlayout.itemAt(0)
                hlayout.removeItem(item)
                if isinstance(item, QWidgetItem):
                    item.widget().close()
            del widgets[idx]
            vlayout.removeItem(hlayouts[idx])
            del hlayouts[idx]
        while n_channels > len(hlayouts):
            idx = len(hlayouts)
            hlayout = QHBoxLayout()
            hlayouts.append(hlayout)
            vlayout.addLayout(hlayout)
            hlayout.addWidget(QLabel("%s #%d: " %
                                     (name.capitalize(), idx + 1)))
            widget = QLineEdit()
            hlayout.addWidget(widget)
            widgets.append(widget)
            variable = path_variables[idx]
            variable.bind_line_edit(widget, "apply-alignment")
            button = QPushButton("...")
            hlayout.addWidget(button)
            button.clicked.connect(partial(button_fn, variable=variable))
コード例 #6
0
ファイル: bridge.py プロジェクト: JanDeVisser/sweattrails
class FormPage(QWidget):
    statusMessage = pyqtSignal(str)

    def __init__(self, parent=None, **kwargs):
        super(FormPage, self).__init__(parent)
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        form_frame = QGroupBox(self)
        self.vbox = QVBoxLayout(form_frame)
        self.form = PropertyFormLayout(None, **kwargs)
        self.vbox.addLayout(self.form)
        self.vbox.addStretch(1)
        self._has_stretch = True
        layout.addWidget(form_frame)

    def _removeStretch(self):
        if self._has_stretch:
            self.vbox.removeItem(self.vbox.itemAt(self.vbox.count() - 1))
            self._has_stretch = False

    def addStretch(self):
        if not self._has_stretch:
            self.vbox.addStretch(1)
            self._has_stretch = True

    def kind(self, k=None):
        return self.form.kind(k)

    def addProperty(self, kind, path, row, col, *args, **kwargs):
        self.form.addProperty(self, kind, path, row, col, *args, **kwargs)

    def get_property_bridge(self, path):
        return self.form.get_property_bridge(path)

    def addWidget(self, widget, *args):
        self._removeStretch()
        self.form.addWidget(widget, *args)

    def addLayout(self, sublayout, *args):
        self._removeStretch()
        self.form.addLayout(sublayout, *args)

    def status_message(self, msg, *args):
        self.statusMessage.emit(msg.format(*args))
コード例 #7
0
ファイル: AttrEditor.py プロジェクト: rwenshen/local_runner
class AttributeEditor(QScrollArea):
    def __init__(self, obj, title: str = 'Object', parent=None):
        super().__init__(parent)
        self.myObj = obj
        self.myTitle = title
        self.myDict = {title: obj}
        self.initUi()

    def initUi(self):
        self.myWidget = QWidget(self)
        self.myLayout = QVBoxLayout()
        self.myLayout.setContentsMargins(5, 5, 5, 5)
        self.myWidget.setLayout(self.myLayout)
        self.setWidget(self.myWidget)
        self.setWidgetResizable(True)

    def updateUi(self):
        while self.myLayout.count():
            item = self.myLayout.takeAt(0)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            else:
                self.myLayout.removeItem(item)

        widget = AWFactory.createWidget(self.myDict, self.myTitle, self,
                                        self.dataChanged.emit)
        self.myLayout.addWidget(widget)
        self.myLayout.addStretch(0)

    dataChanged = pyqtSignal()

    def iterObj(self):
        if isinstance(self.myObj, dict):
            for name in self.myObj:
                yield (name)
        elif '__dict__' in dir(self.myObj):
            for name in vars(self.myObj):
                if name[0] != '_':
                    yield (name)
        else:
            raise TypeError('Unsupported object with type ' + type(self.myObj))
コード例 #8
0
class CustomizeScreen(QWidget):
    def __init__(self, main):
        super().__init__()
        self.main = main

    def initUI(self):
        self.setGeometry(300, 300, 400, 100)
        self.setWindowTitle('Customize Screen')
        # grid = QGridLayout()
        # self.setLayout(grid)
        self.initialized = 3
        self.cancel = False

        self.lbl1 = QLabel('입력: ')
        self.lbl2 = QLabel('입력: ')
        self.lbl3 = QLabel('입력: ')
        self.lbl4 = QLabel('입력: ')
        self.lbl5 = QLabel('입력: ')
        self.lbl6 = QLabel('입력: ')
        self.lbl7 = QLabel('입력: ')
        self.lbl8 = QLabel('입력: ')
        self.lbl9 = QLabel('입력: ')
        self.lbl10 = QLabel('입력: ')
        self.lbl11 = QLabel('')
        self.lbl11.setAlignment(Qt.AlignCenter)

        self.LE1 = QLineEdit()
        self.LE2 = QLineEdit()
        self.LE3 = QLineEdit()
        self.LE4 = QLineEdit()
        self.LE5 = QLineEdit()
        self.LE6 = QLineEdit()
        self.LE7 = QLineEdit()
        self.LE8 = QLineEdit()
        self.LE9 = QLineEdit()
        self.LE10 = QLineEdit()

        self.delButton1 = QPushButton("Del")
        self.delButton2 = QPushButton("Del")
        self.delButton3 = QPushButton("Del")
        self.delButton4 = QPushButton("Del")
        self.delButton5 = QPushButton("Del")
        self.delButton6 = QPushButton("Del")
        self.delButton7 = QPushButton("Del")
        self.delButton8 = QPushButton("Del")
        self.delButton9 = QPushButton("Del")
        self.delButton10 = QPushButton("Del")

        self.addButton = QPushButton("Add")
        self.saveButton = QPushButton("Save")
        self.cancelButton = QPushButton("Cancel")

        self.hbox1 = QHBoxLayout()
        self.hbox2 = QHBoxLayout()
        self.hbox3 = QHBoxLayout()
        self.hbox4 = QHBoxLayout()
        self.hbox5 = QHBoxLayout()
        self.hbox6 = QHBoxLayout()
        self.hbox7 = QHBoxLayout()
        self.hbox8 = QHBoxLayout()
        self.hbox9 = QHBoxLayout()
        self.hbox10 = QHBoxLayout()

        self.hbox11 = QHBoxLayout()
        self.hbox12 = QHBoxLayout()
        self.hbox13 = QHBoxLayout()

        self.vbox1 = QVBoxLayout()
        self.vbox2 = QVBoxLayout()
        self.vbox3 = QVBoxLayout()

        self.hboxList = [
            self.hbox1, self.hbox2, self.hbox3, self.hbox4, self.hbox5,
            self.hbox6, self.hbox7, self.hbox8, self.hbox9, self.hbox10
        ]

        self.vbox1.addLayout(self.hboxList[0])
        self.vbox1.addLayout(self.hboxList[1])
        self.vbox1.addLayout(self.hboxList[2])

        self.vbox2.addLayout(self.hbox13)
        self.vbox2.addLayout(self.hbox11)
        self.vbox2.addLayout(self.hbox12)

        self.vbox3.addLayout(self.vbox1)
        self.vbox3.addLayout(self.vbox2)

        self.hbox1.addWidget(self.lbl1)
        self.hbox1.addWidget(self.LE1)
        self.hbox1.addWidget(self.delButton1)
        self.hbox2.addWidget(self.lbl2)
        self.hbox2.addWidget(self.LE2)
        self.hbox2.addWidget(self.delButton2)
        self.hbox3.addWidget(self.lbl3)
        self.hbox3.addWidget(self.LE3)
        self.hbox3.addWidget(self.delButton3)
        self.hbox4.addWidget(self.lbl4)
        self.hbox4.addWidget(self.LE4)
        self.hbox4.addWidget(self.delButton4)
        self.hbox5.addWidget(self.lbl5)
        self.hbox5.addWidget(self.LE5)
        self.hbox5.addWidget(self.delButton5)
        self.hbox6.addWidget(self.lbl6)
        self.hbox6.addWidget(self.LE6)
        self.hbox6.addWidget(self.delButton6)
        self.hbox7.addWidget(self.lbl7)
        self.hbox7.addWidget(self.LE7)
        self.hbox7.addWidget(self.delButton7)
        self.hbox8.addWidget(self.lbl8)
        self.hbox8.addWidget(self.LE8)
        self.hbox8.addWidget(self.delButton8)
        self.hbox9.addWidget(self.lbl9)
        self.hbox9.addWidget(self.LE9)
        self.hbox9.addWidget(self.delButton9)
        self.hbox10.addWidget(self.lbl10)
        self.hbox10.addWidget(self.LE10)
        self.hbox10.addWidget(self.delButton10)

        self.hbox11.addWidget(self.addButton)
        self.hbox12.addWidget(self.saveButton)
        self.hbox12.addWidget(self.cancelButton)
        self.hbox13.addWidget(self.lbl11)

        self.addButton.clicked.connect(self.Click_addButton)
        self.saveButton.clicked.connect(self.Click_saveButton)
        self.cancelButton.clicked.connect(self.Click_cancelButton)

        self.infoDic = {
            0: {
                'del': self.delButton1,
                'le': self.LE1,
                'lbl': self.lbl1,
                'hbox': self.hbox1
            },
            1: {
                'del': self.delButton2,
                'le': self.LE2,
                'lbl': self.lbl2,
                'hbox': self.hbox2
            },
            2: {
                'del': self.delButton3,
                'le': self.LE3,
                'lbl': self.lbl3,
                'hbox': self.hbox3
            },
            3: {
                'del': self.delButton4,
                'le': self.LE4,
                'lbl': self.lbl4,
                'hbox': self.hbox4
            },
            4: {
                'del': self.delButton5,
                'le': self.LE5,
                'lbl': self.lbl5,
                'hbox': self.hbox5
            },
            5: {
                'del': self.delButton6,
                'le': self.LE6,
                'lbl': self.lbl6,
                'hbox': self.hbox6
            },
            6: {
                'del': self.delButton7,
                'le': self.LE7,
                'lbl': self.lbl7,
                'hbox': self.hbox7
            },
            7: {
                'del': self.delButton8,
                'le': self.LE8,
                'lbl': self.lbl8,
                'hbox': self.hbox8
            },
            8: {
                'del': self.delButton9,
                'le': self.LE9,
                'lbl': self.lbl9,
                'hbox': self.hbox9
            },
            9: {
                'del': self.delButton10,
                'le': self.LE10,
                'lbl': self.lbl10,
                'hbox': self.hbox10
            }
        }

        self.starImgList = [
            'PNG/Number/one.png', 'PNG/Number/two.png', 'PNG/Number/three.png',
            'PNG/Number/four.png', 'PNG/Number/five.png', 'PNG/Number/six.png',
            'PNG/Number/seven.png', 'PNG/Number/eight.png',
            'PNG/Number/nine.png', 'PNG/Number/ten.png'
        ]

        self.initializedList = []
        self.customizeDic = {}
        for i in range(3):
            self.initializedList.append(self.infoDic[i]['hbox'])
        for i in range(3, 10):
            self.infoDic[i]['del'].hide()
            self.infoDic[i]['le'].hide()
            self.infoDic[i]['lbl'].hide()

        for i in range(len(self.infoDic)):
            self.infoDic[i]['del'].clicked.connect(
                lambda state, x=i: self.Click_delButton(x))

        self.setLayout(self.vbox3)
        self.show()

    def Click_addButton(self):
        for i in range(len(self.infoDic)):
            if self.infoDic[i]['hbox'] not in self.initializedList:
                self.initializedList.append(self.infoDic[i]['hbox'])
                self.vbox1.addLayout(self.infoDic[i]['hbox'])
                self.infoDic[i]['del'].show()
                self.infoDic[i]['le'].show()
                self.infoDic[i]['lbl'].show()
                self.initialized += 1
                break

        if self.initialized >= 10:
            self.lbl11.setText("Up to 10 can be entered.")
            self.addButton.hide()
            self.vbox2.removeItem(self.hbox11)

        print(self.initialized)

    def Click_delButton(self, x):
        if self.initialized > 3:
            self.infoDic[x]['le'].setText("")
            self.infoDic[x]['le'].hide()
            self.infoDic[x]['lbl'].hide()
            self.infoDic[x]['del'].hide()
            self.vbox1.removeItem(self.infoDic[x]['hbox'])
            self.initializedList.remove(self.infoDic[x]['hbox'])

        else:
            print("It has to more than 3.")
            self.lbl11.setText("You must enter at least three")
            return

        if self.initialized == 10:
            self.saveButton.hide()
            self.cancelButton.hide()
            self.vbox2.removeItem(self.hbox12)
            self.vbox2.addLayout(self.hbox11)
            self.addButton.show()
            self.vbox2.addLayout(self.hbox12)
            self.saveButton.show()
            self.cancelButton.show()

        self.initialized -= 1

        print(self.initialized)

    def Click_saveButton(self):
        count = 0
        for i in range(len(self.initializedList)):
            if (len(self.infoDic[i]['le'].text()) != 0):
                count += 1

        if count < 3:
            self.lbl11.setText("You must enter at least three")

        else:
            for i in range(len(self.initializedList)):
                if (len(self.infoDic[i]['le'].text()) != 0):
                    self.customizeDic[i] = {
                        'image': self.starImgList[i],
                        'text': self.infoDic[i]['le'].text()
                    }
            print(self.customizeDic)
            self.close()
            self.main.customizeDic = self.customizeDic

    def Click_cancelButton(self):
        self.cancel = True
        self.close()
コード例 #9
0
class CmdWindow(QWidget):
    '''
    The Command window gives the user all the options to create and send a command message
        - Dropdown menus to select an Instance, Topic and Subcommand
        - Fields to enter payload values
        - A time stamped log showing the commands that were successfully sent
    '''
    def __init__(self):
        super().__init__()

        self.title = "Telecommand System"
        self.top = 300
        self.left = 300
        self.width = 1000
        self.height = 800

        self.instance_name = GS_Model.data.instance_chooser
        self.topic_name = GS_Model.data.topic_chooser
        self.subcommand_name = GS_Model.data.subcommand_chooser

        self.payload_entries = []
        self.payload_values = {}

        self.InitWindow()


    def InitWindow(self):
        '''
        Initialize the Command window layout
        '''
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # Destination IP Address
        self.ip_label = QLabel("IP Address:")
        self.ip_textbox = QLineEdit("127.0.0.1")

        self.hbox_ip = QHBoxLayout()
        self.hbox_ip.addWidget(self.ip_label)
        self.hbox_ip.addWidget(self.ip_textbox)

        # Instance Menu
        self.instance_label = QLabel("Instance:")
        self.instance_menu = QComboBox(self)
        for instance in GS_Model.data.instance_keys:
            self.instance_menu.addItem(instance)
        self.instance_menu.currentIndexChanged.connect(self.UpdateInstance)

        self.hbox_instance = QHBoxLayout()
        self.hbox_instance.addWidget(self.instance_label)
        self.hbox_instance.addWidget(self.instance_menu)

        # Topic Menu
        self.topic_label = QLabel("Topic:")
        self.topic_menu = QComboBox(self)
        for topic in GS_Model.data.telecommand_topic_keys:
            self.topic_menu.addItem(topic)
        self.topic_menu.currentIndexChanged.connect(self.UpdateTopic)

        self.hbox_topic = QHBoxLayout()
        self.hbox_topic.addWidget(self.topic_label)
        self.hbox_topic.addWidget(self.topic_menu)

        # Subcommand Menu
        self.subcommand_label = QLabel("Subcommand:")
        self.subcommand_menu = QComboBox(self)
        for subcommand in GS_Model.data.subcommand_keys:
            self.subcommand_menu.addItem(subcommand)
        self.subcommand_menu.currentIndexChanged.connect(self.UpdateSubcommand)

        self.hbox_subcommand = QHBoxLayout()
        self.hbox_subcommand.addWidget(self.subcommand_label)
        self.hbox_subcommand.addWidget(self.subcommand_menu)

        # Payload Menu
        self.payload_label = QLabel("Payload:")

        self.vbox_payload = QVBoxLayout()
        self.vbox_payload.addWidget(self.payload_label)

        # Send Command Button
        self.send_cmd_button = QPushButton("Send Command")
        self.send_cmd_button.clicked.connect(self.SendCommand)

        # Command Log Display
        self.cmd_log_label = QLabel("Command Log:")
        self.cmd_log = QTextBrowser()

        # Save Command Log Button
        self.save_cmd_log = QPushButton("Save Command Log")
        self.save_cmd_log.clicked.connect(self.SaveCommandLog)

        # Overall Layout
        self.layout = QVBoxLayout()
        self.layout.addLayout(self.hbox_ip)
        self.layout.addLayout(self.hbox_instance)
        self.layout.addLayout(self.hbox_topic)
        self.layout.addLayout(self.hbox_subcommand)
        self.layout.addLayout(self.vbox_payload)
        self.layout.addWidget(self.send_cmd_button)
        self.layout.addWidget(self.cmd_log_label)
        self.layout.addWidget(self.cmd_log)
        self.layout.addWidget(self.save_cmd_log)

        self.setLayout(self.layout)

        self.show()


    def UpdateInstance(self):
        '''
        This updates the instance variable when a new instance is selected in the GUI
        '''
        self.instance_name = self.instance_menu.currentText()


    def UpdateTopic(self):
        '''
        This updates the topic variable when a new topic is selected.
        It also updates the Subcommand dropdown and payload entries with new values (if available)
        '''
        self.topic_name = self.topic_menu.currentText()

        if self.topic_name != GS_Model.data.topic_chooser:
            # Update the Subcommand dropdown menu
            GS_Model.data.UpdateSubcommands(self.topic_name)
            self.subcommand_menu.setCurrentIndex(0)
            for i in reversed(range(1, self.subcommand_menu.count())):
                self.subcommand_menu.removeItem(i)

            for subcommand in GS_Model.data.subcommand_keys:
                if subcommand != GS_Model.data.subcommand_chooser:
                    self.subcommand_menu.addItem(subcommand)
            self.subcommand_menu.update()

            # Update payload layout if needed
            eds_id = GS_Controller.control.GetEdsIdFromTopic(self.topic_name)
            payload_struct = GS_Controller.control.GetPayload(eds_id)
            if payload_struct is not None:
                self.UpdatePayload(payload_struct)
            else:
                self.UpdatePayload([])

        else:
            self.subcommand_menu.setCurrentIndex(0)
            for i in reversed(range(1, self.subcommand_menu.count())):
                self.subcommand_menu.removeItem(i)
            self.subcommand_menu.update()

            self.UpdatePayload([])


    def UpdateSubcommand(self):
        '''
        This updates the subcommand variable when a new subcommand is selected in the GUI
        If the new subcommand has new payload values, they are also updated
        '''
        self.subcommand_name = self.subcommand_menu.currentText()
        eds_id = GS_Model.data.subcommand_dict[self.subcommand_name]
        if eds_id != 0:
            payload_struct = GS_Controller.control.GetPayload(eds_id)
            if payload_struct is not None:
                self.UpdatePayload(payload_struct)
            else:
                self.UpdatePayload([])
        else:
            self.UpdatePayload([])


    def ExtractEntries(self, payload_struct):
        '''
        This method generates a list of all the payload entries throughout the payload structure.
        This list is used to update the display with all of the payload entries

        Inputs:
        payload_struct - The payload structure output from GS_Controller.GetPayloadStructure
        '''
        if isinstance(payload_struct, dict):
            for item in list(payload_struct.keys()):
                self.ExtractEntries(payload_struct[item])
        elif isinstance(payload_struct, list):
            for item in payload_struct:
                self.ExtractEntries(item)
        elif isinstance(payload_struct, tuple):
            label = QLabel("{:<30} {}".format(payload_struct[0], payload_struct[1]))
            if payload_struct[2] == 'entry':
                payloadinput = QLineEdit()
            elif payload_struct[2] == 'enum':
                payloadinput = QComboBox()
                for enum_label in list(payload_struct[3].keys()):
                    payloadinput.addItem(enum_label)
            else:
                ErrorMessage("Error", "Something went wrong in the ExtractEntries function")
                return
            self.payload_entries.append((payload_struct[0], payload_struct[1], label, payloadinput))
        else:
            ErrorMessage("Error", "Something went wrong in the ExtractEntries function")


    def UpdatePayload(self, payload_struct):
        '''
        When the payload stucture changes, this method removes the old payload entries
        and adds new ones based on the payload_struct

        Inputs:
        payload_struct - The payload structure output from GS_Controller.GetPayloadStructure
        '''
        # remove the current payload entires in the payload layout (each are their own hbox layouts)
        for i in reversed(range(1, self.vbox_payload.count())):
            layout_item = self.vbox_payload.itemAt(i)
            DeleteItemsOfLayout(layout_item.layout())
            self.vbox_payload.removeItem(layout_item)
        self.vbox_payload.update()

        # add new widgets to represent the new payload entries
        self.payload_entries = []
        self.ExtractEntries(payload_struct)

        for entry in self.payload_entries:
            hbox = QHBoxLayout()
            hbox.addWidget(entry[2])
            hbox.addWidget(entry[3])

            self.vbox_payload.addLayout(hbox)
        self.vbox_payload.update()


    def SendCommand(self):
        '''
        This method takes the input IP Address and payload values and calls
        GS_Controller.control.SendCommand to send the packed message.
        If the command was successfully sent, the command log
        display will be updated with information related to the command.
        '''
        ip_address = self.ip_textbox.text()

        valid_payload = True
        self.payload_values = {}
        for entry in self.payload_entries:
            try:
                value = entry[3].currentText()
            except AttributeError:
                value = entry[3].text()
            if not GS_Controller.ValidPayload(entry, value):
                ErrorMessage("Error", "Invalid input for '{}'".format(entry[0]))
                valid_payload = False
            else:
                self.payload_values[entry[0]] = value

        if valid_payload:
            (cmd_sent, msg, timestamp, port) = GS_Controller.control.SendCommand(ip_address, self.instance_name,
                                                                                 self.topic_name, self.subcommand_name,
                                                                                 self.payload_values)
            if cmd_sent:
                cmd_log_info = f"Command Sent: {timestamp}\n"
                cmd_log_info += "IP: {}   ".format(ip_address)
                cmd_log_info += "Port: {}\n".format(port)
                cmd_log_info += "Instance: {}   ".format(self.instance_name)
                cmd_log_info += "Topic: {}   ".format(self.topic_name)
                if self.subcommand_name == GS_Model.data.subcommand_chooser:
                    cmd_log_info += "Subcommand: None\n"
                else:
                    cmd_log_info += "Subcommand: {}\n".format(self.subcommand_name)
                cmd_log_payload = ''
                payload_keys = list(self.payload_values.keys())
                for key in payload_keys:
                    cmd_log_payload += "{:<30}: ".format(key)
                    cmd_log_payload += "{}\n".format(self.payload_values[key])
                cmd_log_message = "Data to send: \n{}\n".format(GS_Model.HexString(msg, 8))
                cmd_log_string = cmd_log_info + cmd_log_payload + cmd_log_message + '\n'
                self.cmd_log.append(cmd_log_string)
                self.cmd_log.verticalScrollBar().setValue(self.cmd_log.verticalScrollBar().maximum())
            else:
                ErrorMessage("Error", msg)


    def SaveCommandLog(self):
        '''
        This method outputs the command log to a time stamped text file.
        The command log is also cleared when the log file is written.
        '''
        time_str = time.strftime("%Y-%m-%d__%H_%M_%S", time.gmtime())
        if not os.path.isdir("output/"):
            os.mkdir("output/")
        filename = f"output/Command_Log_{time_str}.txt"     
        fout = open(filename, 'w')
        fout.write(self.cmd_log.toPlainText())
        fout.close()
        self.cmd_log.clear()
        self.cmd_log.update()
コード例 #10
0
ファイル: filter.py プロジェクト: razputin42/RainyDM
class Filter:
    locks = dict()

    def __init__(self, filter_content):
        self.filter_content = filter_content
        self.filter = dict()
        self.frame = QFrame()
        self.frame.setObjectName("Filter_frame")
        self.frame.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)
        actual_layout = QVBoxLayout()
        widget_frame = QFrame()
        self.layout = QVBoxLayout()
        widget_frame.setLayout(self.layout)
        actual_layout.addWidget(widget_frame)
        actual_layout.addStretch(1)
        self.filter_names = []
        self.frame.setLayout(actual_layout)
        self.frame.setHidden(True)

    def add_range(self, name, capitalize=False):
        min_input = QLineEdit()
        max_input = QLineEdit()
        min_input.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        min_input.setMaximumWidth(50)
        max_input.setMaximumWidth(50)
        if capitalize:
            name = name.capitalize()
        title = QLabel(name)
        dash = QLabel("-")
        frame = QFrame()
        layout = QHBoxLayout()
        layout.addWidget(min_input)
        layout.addStretch(0)
        layout.addWidget(dash)
        layout.addStretch(0)
        layout.addWidget(max_input)
        frame.setLayout(layout)
        # frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.layout.addWidget(title)
        self.layout.addWidget(frame)

        min_input.textChanged.connect(
            lambda: self.set_range_filter(name, min_input, max_input))
        max_input.textChanged.connect(
            lambda: self.set_range_filter(name, min_input, max_input))

    def set_range_filter(self, name, min_input, max_input):
        name = name.lower()
        minimum = -9001
        maximum = 9001
        try:
            minimum = int(min_input.text())
        except:
            pass
        try:
            maximum = int(max_input.text())
        except:
            pass

        if minimum == -9001 and maximum == 9001:
            if name in self.filter.keys():
                del self.filter[name]
        else:
            self.filter[name] = [minimum, maximum]
        self.filter_content()

    def add_dropdown(self,
                     name,
                     options,
                     suboptions=None,
                     default=None,
                     alphabetical=True):
        if alphabetical:
            options.sort()
        combo_box = QComboBox()
        combo_box.addItem("Any")
        combo_box.addItems(options)
        if suboptions is not None:
            sub_combo_box = QComboBox()
            sub_combo_box.setHidden(True)
        else:
            sub_combo_box = None
        label = QLabel(name)
        self.filter_names.append(name)
        self.layout.addWidget(label)
        self.layout.addWidget(combo_box)
        if suboptions is not None:
            self.layout.addWidget(sub_combo_box)
            sub_combo_box.currentIndexChanged.connect(
                lambda: self.set_sub_filters(name, combo_box, sub_combo_box))
        combo_box.currentIndexChanged.connect(lambda: self.set_filters(
            name, combo_box, sub_combo_box, suboptions))

        if default is not None:
            index = combo_box.findText(default, QtCore.Qt.MatchFixedString)
            if index >= 0:
                combo_box.setCurrentIndex(index)

    def set_sub_filters(self, name, combo_box, sub_combo_box):
        name = name.lower()
        main = combo_box.currentText().lower()
        sub = sub_combo_box.currentText().lower()
        if sub == "any":
            self.filter[name] = main + ".*"
        else:
            self.filter[name] = main + ".*(\ \(|\,\ )(" + sub + ").*"
        self.filter_content()

    def set_filters(self,
                    name,
                    combo_box,
                    sub_combo_box=None,
                    suboptions=None):
        main = combo_box.currentText()
        sub_cond = sub_combo_box is not None
        if sub_cond:
            sub = sub_combo_box.currentText()

        name = name.lower()
        if main == "Any" and name in self.filter.keys():
            del self.filter[name]
            if sub_cond:
                sub_combo_box.setHidden(True)
        else:
            if sub_cond:
                if main in suboptions.keys():
                    _suboptions = [
                        subopt for subopt in suboptions[main]
                        if subopt != "Any"
                    ]  # remove Any as suboption
                    sub_combo_box.setHidden(False)
                    sub_combo_box.clear()
                    sub_combo_box.addItem("Any")
                    sub_combo_box.addItems(_suboptions)
                else:
                    sub_combo_box.clear()
                    sub_combo_box.setHidden(True)
            self.filter[name] = main + ".*"
        # print(self.filter[name])
        self.filter_content()

    def lock(self, attr, value):
        self.locks[attr] = value

    def get_frame(self):
        return self.frame

    def toggle_hidden(self):
        if self.frame.isHidden():
            self.frame.setHidden(False)
        else:
            self.frame.setHidden(True)

    def evaluate_filter(self, entry):
        cond = True
        for key, arg in self.locks.items():
            if not hasattr(entry, key) or getattr(entry, key) != arg:
                return False
        for key, arg in self.filter.items():
            if not hasattr(entry, key):
                # print("Wrong filter key passed to entry in SearchableTable")
                return False
            attr = getattr(entry, key)
            if type(arg) is str and type(
                    attr
            ) is str:  # single attribute, single argument. Easy as pie
                p = re.compile('{}'.format(arg), re.IGNORECASE)
                cond = cond and (p.match(attr))
            elif type(
                    attr
            ) is list:  # single argument, multiple attributes, eval individually for each element
                p = re.compile('{}'.format(arg), re.IGNORECASE)
                cond = cond and any([p.match(_attr) for _attr in attr])
            elif type(
                    arg
            ) is list:  # numerical range, must be inbetween two values
                if attr is None or None in arg:
                    continue
                attr = eval("float({})".format(attr))
                cond = cond and (arg[0] <= attr <= arg[1])

        return cond

    def clear_filters(self):
        for i in reversed(range(self.layout.count())):
            self.layout.removeItem(self.layout.itemAt(i))
        self.filter = dict()
コード例 #11
0
ファイル: SchemaEditor.py プロジェクト: Aqueti/MongoViewer
class MainWindow(QWidget):
    ##
    # \brief Initialization Function
    def __init__(self):
        super(MainWindow, self).__init__()

        #Default variables
        self.valid = False  #Field to determine if the value is valid
        self.selectorLayout = None  #Layout used for selecting a specific source
        self.sources = ["none", "text", "file", "database"]
        self.source = {"type": None}
        self.dests = ["console", "file"]
        self.dest = {"type": "console"}

        self.sourceValue = None
        self.sourceSchema = None

        #Determine screen settings
        geo = self.frameGeometry()
        self.width = QDesktopWidget().availableGeometry().width()
        self.height = QDesktopWidget().availableGeometry().height()

        #Define window par meters
        self.resize(self.width * .5, self.height * .5)
        self.setWindowTitle("Aqueti Schema Editor")
        self.show()

        #create Layouts in UI
        self.titleLayout = QHBoxLayout()
        self.mainLayout = QVBoxLayout()
        self.sourceLayout = QHBoxLayout()
        self.destLayout = QHBoxLayout()
        self.valueLayout = QVBoxLayout()
        self.buttonLayout = QHBoxLayout()

        #Create frames
        self.sourceFrame = QFrame()
        self.destFrame = QFrame()
        self.valueFrame = QFrame()
        self.sourceFrame.setFrameStyle(QFrame.Box)
        self.valueFrame.setFrameStyle(QFrame.Box)
        self.destFrame.setFrameStyle(QFrame.Box)

        self.sourceFrame.setLayout(self.sourceLayout)
        self.destFrame.setLayout(self.destLayout)
        self.valueFrame.setLayout(self.valueLayout)
        self.valueFrame.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)

        #Create Scoll Area for valueFrame
        self.valueScrollArea = QScrollArea()
        self.valueScrollArea.updateGeometry()
        self.valueScrollArea.setWidget(self.valueFrame)
        self.valueScrollArea.setWidgetResizable(True)

        #Create title
        title = QLabel()
        title.setText("Aqueti Schema Editor")
        self.titleLayout.addWidget(title)

        #Add persistent source items
        sourceTitle = QLabel()
        sourceTitle.setText("Source:")
        self.sourceCombo = QComboBox()
        self.sourceCombo.addItems(self.sources)
        self.sourceCombo.currentTextChanged.connect(
            lambda: self.sourceChangeCallback())
        selectSourceButton = QPushButton("Load")
        self.sourceLayout.addWidget(sourceTitle)
        self.sourceLayout.addWidget(self.sourceCombo)

        self.sourceMetaLayout = QHBoxLayout()
        self.sourceMetaLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize)
        self.sourceLayout.addLayout(self.sourceMetaLayout)
        self.sourceLayout.addWidget(selectSourceButton)

        #Add persistent dest
        destTitle = QLabel()
        destTitle.setText("Dest:")
        self.destCombo = QComboBox()
        self.destCombo.addItems(self.dests)
        self.destCombo.currentTextChanged.connect(
            lambda: self.destChangeCallback())
        selectDestButton = QPushButton("Load")
        self.destLayout.addWidget(destTitle)
        self.destLayout.addWidget(self.destCombo)

        self.destMetaLayout = QHBoxLayout()
        self.destMetaLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize)
        self.destLayout.addLayout(self.destMetaLayout)
        self.destLayout.addWidget(selectDestButton)

        #Add Submit Button
        self.submitButton = QPushButton("Submit")
        self.submitButton.clicked.connect(lambda: self.submitCallback())
        self.buttonLayout.addWidget(self.submitButton)

        #Add cancel Button
        cancelButton = QPushButton("Cancel")
        cancelButton.clicked.connect(lambda: self.cancelCallback())
        self.buttonLayout.addWidget(cancelButton)

        #Add Layouts and draw
        self.mainLayout.addLayout(self.titleLayout)
        self.mainLayout.addWidget(self.sourceFrame)
        self.mainLayout.addWidget(self.destFrame)

        #        self.mainLayout.addWidget( self.valueFrame )
        self.mainLayout.addWidget(self.valueScrollArea)
        #        self.mainLayout.addStretch(1)
        self.mainLayout.addLayout(self.buttonLayout)
        self.draw()

    ##
    # \brief updates the source Layout
    def updateSourceLayout(self):
        #Remove current layout information
        #Remove all widgets from the current layout
        while self.sourceMetaLayout.count():
            item = self.sourceMetaLayout.takeAt(0)
            self.sourceMetaLayout.removeItem(item)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            try:
                item.deleteLater()
            except:
                pass

        #Find what our current source is and set the appropriate index
        index = 0
        for i in range(0, self.sourceCombo.count()):
            if self.sourceCombo.itemText(i) == self.source["type"]:
                index = i

        self.sourceCombo.setCurrentIndex(index)

        #Add fields based on source type
        if self.source["type"] == "file":
            #Add filename
            fileLabel = QLabel()
            fileLabel.setText("file: ")

            try:
                name = self.source["filename"]
            except:
                name = ""

            self.sourceFilenameBox = QLineEdit()
            self.sourceFilenameBox.setSizePolicy(QSizePolicy.Expanding,
                                                 QSizePolicy.Minimum)
            self.sourceFilenameBox.setText(name)
            #            self.sourceFilenameBox.readOnly = True
            #            self.sourceFilenameBox.sizeHint()
            #            self.sourceFilenameBox.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)

            self.sourceMetaLayout.addWidget(fileLabel)
            self.sourceMetaLayout.addWidget(self.sourceFilenameBox)

#        #Add a submitSource Button
#        selectSourceButton = QPushButton("Load")
#        selectSourceButton.clicked.connect( lambda: self.sourceChangeCallback())

#        self.sourceLayout.addWidget(selectSourceButton)

#        self.sourceLayout.addStretch(1)

##
# \brief updates the destination layout
#

    def updateDestLayout(self):
        #Remove current layout information
        #Remove all widgets from the current layout
        while self.destMetaLayout.count():
            item = self.destMetaLayout.takeAt(0)
            self.destMetaLayout.removeItem(item)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            try:
                item.deleteLater()
            except:
                pass
        """
        #############################################
        # Layout to select a destination
        #############################################
        destTitle = QLabel()
        destTitle.setText("Dest:")
        self.destCombo = QComboBox()
        self.destCombo.addItems(self.dests)
        """

        #Find what our current dest is and set the appropriate index
        index = 0
        for i in range(0, self.destCombo.count()):
            if self.destCombo.itemText(i) == self.dest["type"]:
                index = i

        self.destCombo.setCurrentIndex(index)
        self.destCombo.currentTextChanged.connect(
            lambda: self.destChangeCallback())

        #        self.destLayout.addWidget(destTitle)
        #        self.destLayout.addWidget(self.destCombo)
        #        self.destLayout.addStretch(1)

        ####
        # Fill in details base on dest tpye
        ####
        if self.dest["type"] == "console":
            pass
        elif self.dest["type"] == "file":
            fileLabel = QLabel()
            fileLabel.setText("file: ")

            try:
                name = self.dest["filename"]
            except:
                name = ""

            self.fileNameBox = QLineEdit()
            self.fileNameBox.setText(name)

            #            self.destMetaLayout.addWidget(fileLabel)
            self.destMetaLayout.addWidget(self.fileNameBox)

    ##
    # \brief function that is called when the source is changed
    #
    def destChangeCallback(self):
        print("Changing dest")

        newType = self.destCombo.itemText(self.destCombo.currentIndex())

        print("New Type: " + str(newType))

        if newType != self.dest["type"]:
            self.dest = {}

        self.dest["type"] = newType

        if self.dest["type"] == "console":
            pass

        elif self.dest["type"] == "file":
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            destName, _ = QFileDialog.getSaveFileName(
                self,
                "QFileDialog.getSaveFileName()",
                "",
                "All Files (*);;JSON Files (*.json)",
                options=options)

            self.dest["filename"] = str(destName)

        else:
            print("Unsupported Type")

        self.draw()

    ##
    # \brief Update the value layout
    def updateValueLayout(self):
        #Remove all widgets from the current layout
        while self.valueLayout.count():
            item = self.valueLayout.takeAt(0)
            self.valueLayout.removeItem(item)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
            try:
                item.deleteLater()
            except:
                pass

        #If we have data, let's display it
        if self.sourceSchema != None:

            valueTitle = QLabel()
            valueTitle.setText("Schema")

            self.schemaWidget = SmartWidget().init("Schema",
                                                   self.sourceValue,
                                                   self.sourceSchema,
                                                   showSchema=False)
            self.valueLayout.addWidget(self.schemaWidget.frame)

        #Disable the submit button if we don't have a schema
        if self.sourceSchema == None:
            self.submitButton.setEnabled(False)
        else:
            self.submitButton.setEnabled(True)

        self.setLayout(self.mainLayout)

    ##
    # \brief redraws all dynamic layouts
    def draw(self):
        self.updateDestLayout()
        self.updateSourceLayout()
        self.updateValueLayout()

    ##
    # \brief callback for when the source type changes
    #
    def sourceChangeCallback(self):

        #SDF Add popup to notify of schema loss

        #Clear the schema to disable the submit button
        self.sourceSchema = None
        self.source["type"] = self.sourceCombo.itemText(
            self.sourceCombo.currentIndex())

        if self.source["type"] == "none":
            self.sourceSchema = {"bsonType": "object"}

        #If we are a file  read the file contents as the value
        elif self.source["type"] == "file":
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            sourceName, _ = QFileDialog.getOpenFileName(
                self,
                "QFileDialog.getOpenFileName()",
                "",
                "All Files (*);;JSON Files (*.json)",
                options=options)

            self.source["filename"] = str(sourceName)
            print("Loading: " + str(self.source["filename"]))

            with open(self.source["filename"]) as json_file:
                self.sourceSchema = json.load(json_file)

            print("Loaded Schema:" +
                  str(json.dumps(self.sourceSchema, indent=4)))

        self.updateSourceLayout()
        self.updateValueLayout()

    ##
    #\brief callback to get result from SmartWidget
    #
    # This function assumes that the schema is done. It will produce a popup
    # asking where and how to save the data
    #
    def submitCallback(self):
        schema = self.schemaWidget.getSchema()

        if self.dest["type"] == "console":
            print()
            print("Schema: (" + str(time.time()) + ")")
            print(json.dumps(schema, indent=4))

        elif self.dest["type"] == "file":
            print("Writing to: " + str(self.dest["filename"]))
            with open(self.dest["filename"], 'w') as outfile:
                json.dump(schema, outfile, indent=4)
        else:
            print("Source type: " + str(self.dest["type"]) +
                  " is not currently supported")

        self.close()

        #Use save pop-up to save data
        #self.saveWindow = SaveDataWindow(self.source, schema, self.saveCallback )

        print(str(time.time()) + "- schema:")
        print(str(schema))

    ##
    # \brief Function called after data is saved
    #
    def saveCallback(self, success):
        print("Data Result: " + str(success))

    ##
    # \brief Cancels the change and exits
    #
    def cancelCallback(self):
        print("Exited. No changes were saved")
        sys.exit(1)
コード例 #12
0
class LiveWidget(QWidget):
    """

    """
    def __init__(self):
        """

        """
        super(LiveWidget, self).__init__()

        self.pot_btn = QPushButton('PotPlayer播放')

        self.vlc_btn = QPushButton('VLC播放')
        self.vlc_widget = VLCWidget()

        self.player_widget = QWidget()
        self.player_layout = QVBoxLayout()
        self._layout = QVBoxLayout()

        self.set_player_widget()

        self.init_ui()

    def init_ui(self):
        """

        :return:
        """
        # player_layout = QVBoxLayout()
        self.player_layout.setContentsMargins(0, 0, 0, 0)
        self.player_layout.setSpacing(0)
        self.player_layout.addWidget(self.player_widget)

        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        main_layout.addLayout(self.player_layout)
        self.setLayout(main_layout)

        self.setStyleSheet(
            "background-image:url(./resources/img/live_null.png); ")

    def clear_layout(self):
        """

        :return:
        """
        for i in range(self._layout.count()):
            print("i {0}".format(i))
            self._layout.removeItem(self._layout.itemAt(i))
        self._layout.setParent(None)
        self.player_layout.removeItem(self._layout)

    def set_widget_visible(self, visible):
        """

        :return:
        """
        if visible:
            # self.vlc_widget.setVisible(True)
            self.vlc_widget.show()
        else:
            # self.vlc_widget.setVisible(False)
            self.vlc_widget.hide()

    def set_player_widget(self, widget=False):
        """

        :param widget:
        :return:
        """
        # self.clear_layout()

        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)

        self._layout.addWidget(self.vlc_widget)

        self.set_widget_visible(widget)

        self.player_widget.setLayout(self._layout)
コード例 #13
0
ファイル: meta.py プロジェクト: zhiiker/FeelUOwn
class TableMetaWidget(MetaWidget):
    def __init__(self, parent=None):
        super().__init__(parent=parent)

        self.cover_label = CoverLabel(self)
        # these three widgets are in right layout
        self.title_label = QLabel(self)
        self.meta_label = QLabel(self)
        # this spacer item is used as a stretch in right layout,
        # it's  width and height is not so important, we set them to 0
        self.text_spacer = QSpacerItem(0, 0, QSizePolicy.Minimum,
                                       QSizePolicy.Expanding)

        self.title_label.setTextFormat(Qt.RichText)
        self.meta_label.setTextFormat(Qt.RichText)

        self._setup_ui()
        self._refresh()

    def _setup_ui(self):
        self.cover_label.setMinimumWidth(150)
        self.cover_label.setMaximumWidth(200)
        self._v_layout = QVBoxLayout(self)
        self._h_layout = QHBoxLayout()
        self._right_layout = QVBoxLayout()
        self._right_layout.addStretch(0)
        self._right_layout.addWidget(self.title_label)
        self._right_layout.addWidget(self.meta_label)
        self._h_layout.addWidget(self.cover_label)
        self._h_layout.setAlignment(self.cover_label, Qt.AlignTop)
        self._h_layout.addLayout(self._right_layout)
        self._h_layout.setStretchFactor(self._right_layout, 2)
        self._h_layout.setStretchFactor(self.cover_label, 1)
        self._h_layout.setContentsMargins(0, 30, 0, 0)
        self._h_layout.setSpacing(30)
        self._v_layout.addLayout(self._h_layout)

        self._right_layout.setContentsMargins(0, 0, 0, 0)
        self._right_layout.setSpacing(5)

        # left margin is same as toolbar left margin
        self.layout().setContentsMargins(30, 0, 30, 0)
        self.layout().setSpacing(0)

    def add_tabbar(self, tabbar):
        self._right_layout.addWidget(tabbar)
        self._right_layout.setAlignment(self.parent().tabbar, Qt.AlignLeft)

    def set_cover_pixmap(self, pixmap):
        if pixmap is not None:
            self.cover_label.show()
            self._right_layout.addItem(self.text_spacer)
        self.cover_label.show_pixmap(pixmap)
        self.updateGeometry()

    def on_property_updated(self, name):
        if name in ('created_at', 'updated_at', 'songs_count', 'creator'):
            self._refresh_meta_label()
        elif name in ('title', 'subtitle'):
            self._refresh_title()
        elif name == 'cover':
            self._refresh_cover()

    def _refresh_meta_label(self):
        creator = self.creator
        # icon: 👤
        creator_part = creator if creator else ''
        created_part = updated_part = songs_count_part = ''
        if self.updated_at:
            updated_part = '🕒 更新于 <code style="font-size: small">{}</code>'\
                .format(self.updated_at.strftime('%Y-%m-%d'))
        if self.created_at:
            created_part = '🕛 创建于 <code style="font-size: small">{}</code>'\
                .format(self.created_at.strftime('%Y-%m-%d'))
        if self.songs_count is not None:
            text = self.songs_count if self.songs_count != -1 else '未知'
            songs_count_part = '<code style="font-size: small">{}</code> 首歌曲'\
                .format(text)
        if creator_part or updated_part or created_part or songs_count_part:
            parts = [
                creator_part, created_part, updated_part, songs_count_part
            ]
            valid_parts = [p for p in parts if p]
            content = ' • '.join(valid_parts)
            text = '<span>{}</span>'.format(content)
            # TODO: add linkActivated callback for meta_label
            self.meta_label.setText(text)
            self.meta_label.show()
        else:
            self.meta_label.hide()

    def _refresh_cover(self):
        if not self.cover:
            self.cover_label.hide()
            self._right_layout.removeItem(self.text_spacer)
        else:
            self._right_layout.addItem(self.text_spacer)
        self.updateGeometry()

    def _refresh_title(self):
        if self.title:
            self.title_label.show()
            self.title_label.setText('<h2>{}</h2>'.format(self.title))
        else:
            self.title_label.hide()

    def _refresh(self):
        self._refresh_title()
        self._refresh_meta_label()
        self._refresh_cover()

    def sizeHint(self):
        super_size = super().sizeHint()
        if self.cover_label.isVisible():
            margins = self.layout().contentsMargins()
            v_margin = margins.top() + margins.bottom()
            height = self.cover_label.sizeHint().height() + v_margin
            return QSize(super_size.width(), height)
        return super_size

    def resizeEvent(self, e):
        super().resizeEvent(e)
        # HELP: think about a more elegant way
        # Currently, right panel draw background image on meta widget
        # and bottom panel, when meta widget is resized, the background
        # image will also be scaled, so we need to repaint on bottom panel
        # and meta widget. However, by default, qt will only repaint
        # meta widget in this case, so we trigger bottom panel update manually
        self.parent()._app.ui.bottom_panel.update()
コード例 #14
0
class ConsolePanel(QFrame):
    def __init__(self, master):
        super().__init__(master)

        self.cbTimestamp = QCheckBox("Timestamp", self)
        self.cbErrors = QCheckBox("Errors", self)
        self.cbInfo = QCheckBox("Info", self)
        self.cbOrders = QCheckBox("Orders", self)
        self.cbAnswers = QCheckBox("Answers", self)
        self.cbSensors = QCheckBox("Sensors", self)

        self.cbList = [self.cbTimestamp, self.cbErrors, self.cbInfo, self.cbOrders, self.cbAnswers, self.cbSensors]
        for cb in self.cbList:
            cb.setChecked(True)
            cb.stateChanged.connect(self.settings_changed)

        self.console = QTextEdit(self)
        self.console.setReadOnly(True)
        self.consoleVScrollBar = self.console.verticalScrollBar()
        self.font = "Consolas"
        self.fontSize = 9
        self.fontSize_small = 7
        self.timestampColor = QColor(119, 180, 177)
        self.textColor = QColor(197, 200, 198)
        self.errorColor = QColor(195, 48, 39)
        self.orderColor = QColor(1, 160, 228)
        self.answerColor = QColor(1, 162, 82)
        self.sensorColor = QColor(1, 160, 160)

        self.console.setStyleSheet("""
            background-color: rgb(29, 31, 33);
            color: rgb(197, 200, 198);
        """)

        self.consoleText = ""

        self.margin = 41 # Parameter to tune to make things work
        self.width_needed = None

        grid = QGridLayout()
        self.cbArea = QVBoxLayout()
        grid.addLayout(self.cbArea, 0, 0)
        grid.addWidget(self.console, 1, 0, 1, 2)
        grid.setRowStretch(1, 1)
        grid.setColumnStretch(1, 1)
        self.setLayout(grid)
        self.organizeWidgets(init=True)

    def resizeEvent(self, event):
        w = self.cbArea.minimumSize().width()
        availableWidth = event.size().width() - self.margin
        if availableWidth > 30:
            if availableWidth <= w or (self.width_needed is not None and availableWidth > w + self.width_needed):
                self.organizeWidgets(False, availableWidth - 30)

    def organizeWidgets(self, init, availableWidth=None):
        if not init:
            for i in reversed(range(self.cbArea.count())):
                item = self.cbArea.itemAt(i)
                if isinstance(item, QLayoutItem):
                    layout = item.layout()
                    for j in reversed(range(layout.count())):
                        widget = layout.itemAt(j).widget()
                        if widget is not None:
                            layout.removeWidget(widget)
                        else:
                            print("ERR")
                else:
                    print("Err")
                self.cbArea.removeItem(item)
                item.deleteLater()

        self.width_needed = None
        i = 0
        while i < len(self.cbList):
            line = QHBoxLayout()
            columnCount = 0
            while True:
                if availableWidth is not None and line.minimumSize().width() >= availableWidth:
                    if columnCount > 1:
                        i -= 1
                        line.removeWidget(self.cbList[i])
                    overlap = line.minimumSize().width() - availableWidth
                    if self.width_needed is None:
                        self.width_needed = overlap
                    else:
                        self.width_needed = min(self.width_needed, overlap)
                    break
                elif i >= len(self.cbList):
                    break
                else:
                    line.addWidget(self.cbList[i])
                    i +=1
                    columnCount += 1
            self.cbArea.addLayout(line)

    def formatTextToConsole(self, text):
        textLines = text.splitlines(keepends=True)
        lineNb = 0
        for line in textLines:
            lineNb += 1
            sLine = line.split('_', maxsplit=2)
            if len(sLine) != 3:
                # print("Incorrect line nb", lineNb, ":", line)
                continue
            try:
                int(sLine[0])
            except ValueError:
                print("Incorrect timestamp :", sLine[0])
                continue
            if sLine[1] == INFO_CHANNEL_NAME:
                if not self.cbInfo.isChecked():
                    continue
                color = self.textColor
            elif sLine[1] == ERROR_CHANNEL_NAME:
                if not self.cbErrors.isChecked():
                    continue
                color = self.errorColor
            elif sLine[1] == TRACE_CHANNEL_NAME:
                if not self.cbInfo.isChecked():
                    continue
                color = self.textColor
            elif sLine[1] == SPY_ORDER_CHANNEL_NAME:
                if not self.cbOrders.isChecked():
                    continue
                color = self.orderColor
            elif sLine[1] == ANSWER_DESCRIPTOR:
                if not self.cbAnswers.isChecked():
                    continue
                color = self.answerColor
            elif sLine[1] == SENSOR_CHANNEL_NAME:
                if not self.cbSensors.isChecked():
                    continue
                color = self.sensorColor
            else:
                print("Incorrect line type :", sLine[1])
                continue
            if self.cbTimestamp.isChecked():
                self.console.setTextColor(self.timestampColor)
                self.console.setCurrentFont(QFont(self.font, self.fontSize_small))
                self.console.insertPlainText(sLine[0] + " ")
            self.console.setTextColor(color)
            self.console.setCurrentFont(QFont(self.font, self.fontSize))
            self.console.insertPlainText(sLine[2])

    def setText(self, newText):
        self.consoleText = newText
        self.console.clear()
        self.formatTextToConsole(newText)
        self.consoleVScrollBar.setValue(self.consoleVScrollBar.maximum())

    def appendText(self, text):
        self.consoleText += text
        self.formatTextToConsole(text)
        self.consoleVScrollBar.setValue(self.consoleVScrollBar.maximum())

    def settings_changed(self):
        scrollValue = self.consoleVScrollBar.value()
        self.console.clear()
        self.formatTextToConsole(self.consoleText)
        self.consoleVScrollBar.setValue(scrollValue)
コード例 #15
0
class EditDialog(QMainWindow):
    def __init__(self, mood, parent=None):
        super().__init__(parent)

        # Top level layout
        self.main_widget = QWidget()
        self.layout = QVBoxLayout()

        # Tracks have a separate layout
        self.new_tracks = []
        self.track_layout = QVBoxLayout()

        for track in mood.playlist.playlist:
            url = track[0]
            title = track[1]

            self.add_track(url, title)

        # Add parameters
        self.update_box = QLineEdit(mood.label, self)
        self.layout.addWidget(self.update_box)

        #self.layout.addWidget(QLabel("Tracks:", self))

        self.layout.addLayout(self.track_layout)

        add_button = QPushButton("+", self)
        add_button.setMaximumSize(22, 22)
        add_button.clicked.connect(self.pick_track)
        self.layout.addWidget(add_button)

        self.layout.addStretch(1)

        save_button = QPushButton("Save", self)
        save_button.clicked.connect(lambda: self.save_settings(mood))
        self.layout.addWidget(save_button)

        self.main_widget.setLayout(self.layout)
        self.setCentralWidget(self.main_widget)

        # Set window properties
        self.setGeometry(400, 400, 320, 240)
        self.setWindowTitle('Settings')

        self.show()

    def pick_track(self):
        url = QFileDialog.getOpenFileName(self, 'Add Track')

        if url[0]:
            title = os.path.split(url[0])[-1]
            self.add_track(url[0], title)

    def add_track(self, url, title):
        idx = len(self.new_tracks)

        label = QLabel(title, self)
        label.setMinimumSize(100, 22)
        remove = QPushButton("-", self)
        remove.setMaximumSize(22, 22)
        mv_up = QPushButton("â–²", self)
        mv_up.setMaximumSize(22, 22)
        mv_down = QPushButton("â–¼", self)
        mv_down.setMaximumSize(22, 22)

        single_track = QHBoxLayout()

        single_track.addWidget(label)
        single_track.addWidget(remove)
        single_track.addWidget(mv_up)
        single_track.addWidget(mv_down)
        single_track.setSpacing(5)

        list_item = (url, title, single_track)
        remove.clicked.connect(lambda: self.remove_track(list_item))
        mv_up.clicked.connect(lambda: self.up_track(list_item))
        mv_down.clicked.connect(lambda: self.down_track(list_item))

        self.new_tracks.append(list_item)
        self.track_layout.addLayout(single_track)

    def remove_track(self, list_item):
        url, title, single_track = list_item
        self.track_layout.removeItem(single_track)

        # Remove all the widgets
        for i in reversed(range(single_track.count())):
            single_track.itemAt(i).widget().setParent(None)

        # Delete the single track layout
        single_track.deleteLater()

        # Remove from list
        try:
            self.new_tracks.remove(list_item)
        except ValueError:
            pass

    def up_track(self, list_item):
        old_idx = self.new_tracks.index(list_item)
        if old_idx > 0:
            new_idx = old_idx - 1
            self.new_tracks.remove(list_item)
            self.new_tracks.insert(new_idx, list_item)

            _, _, single_track = list_item
            self.track_layout.removeItem(single_track)
            self.track_layout.insertItem(new_idx, single_track)

    def down_track(self, list_item):
        old_idx = self.new_tracks.index(list_item)
        if old_idx < len(self.new_tracks) - 1:
            new_idx = old_idx + 1
            self.new_tracks.remove(list_item)
            self.new_tracks.insert(new_idx, list_item)

            _, _, single_track = list_item
            self.track_layout.removeItem(single_track)
            self.track_layout.insertItem(new_idx, single_track)

    def save_settings(self, mood):
        # Update label
        new_label = self.update_box.text()
        if new_label != mood.label:
            mood.label = new_label
            mood.play_button.setText(mood.label)

        # Update playlist with new tracks
        mood.playlist.clear()
        for track in self.new_tracks:
            mood.playlist.add(track[0])

        mood.playlist.restart()
コード例 #16
0
ファイル: rosconfigdialog.py プロジェクト: Diegojnb/JdeRobot
class TopicsTab(QWidget):
    configChanged = pyqtSignal()
    def __init__(self):
        super(QWidget, self).__init__()
        self.config = None
        self.count = 0
        self.topicRows = {}

        self.nameEdit = QLineEdit()
        self.dataTypeComboBox = QComboBox()
        self.fillDataTypes()
        self.opTypeComboBox = QComboBox()
        self.opTypeComboBox.addItem('sub', 'Subscribe')
        self.opTypeComboBox.addItem('pub', 'Publish')
        self.addButton = QPushButton('Add')
        self.addButton.clicked.connect(self.addClicked)

        self.mainLayout = QVBoxLayout()
        rowLayout = QHBoxLayout()
        rowLayout.addWidget(self.nameEdit)
        rowLayout.addWidget(self.dataTypeComboBox)
        rowLayout.addWidget(self.opTypeComboBox)
        rowLayout.addWidget(self.addButton)
        rowContainer = QWidget()
        rowContainer.setLayout(rowLayout)
        rowContainer.setObjectName('titleRow')
        self.mainLayout.addWidget(rowContainer)
        self.setLayout(self.mainLayout)


    def fillDataTypes(self):
        rosTypes = Interfaces.getRosMessageTypes()
        for type in rosTypes:
            concatType = type['typeDir'] + '/' + type['type']
            self.dataTypeComboBox.addItem(concatType, concatType)


    def addTopicRow(self, name, type, opType):
        rowLayout = QHBoxLayout()
        rowLayout.addWidget(QLabel(name))
        rowLayout.addWidget(QLabel(type))
        rowLayout.addWidget(QLabel(opType))
        removeButton = QPushButton('Remove')
        removeButton.clicked.connect(self.removeTopicClicked)
        removeButton.setObjectName(str(self.count))
        rowLayout.addWidget(removeButton)
        rowContainer = QWidget()
        rowContainer.setLayout(rowLayout)
        rowContainer.setObjectName('row' + str(self.count))
        self.mainLayout.addWidget(rowContainer)
        self.topicRows[self.count] = rowContainer
        self.count += 1


    def addClicked(self):
        if self.config is not None:
            self.config.addTopic(self.count, self.nameEdit.text(), self.dataTypeComboBox.currentData(), self.opTypeComboBox.currentData())
            self.addTopicRow(self.nameEdit.text(), self.dataTypeComboBox.currentData(), self.opTypeComboBox.currentData())
            self.nameEdit.setText('')
            self.configChanged.emit()

    def removeTopicClicked(self):
        if self.config is not None:
            itemToRemove = None
            for i in range(self.mainLayout.count()):
                if self.mainLayout.itemAt(i).widget().objectName() == 'row' + self.sender().objectName():
                    itemToRemove = self.mainLayout.itemAt(i)
                    break
            if itemToRemove is not None:
                self.mainLayout.removeItem(itemToRemove)
                itemToRemove.widget().setParent(None)
                self.mainLayout.update()
                self.configChanged.emit()
            self.config.removeTopic(int(self.sender().objectName()))
            del self.topicRows[int(self.sender().objectName())]


    def clearAllRows(self):
        clearList = []
        for i in range(self.mainLayout.count()):
            item = self.mainLayout.itemAt(i)
            if item.widget().objectName() != 'titleRow':
                clearList.append(item)

        for item in clearList:
            self.mainLayout.removeItem(item)
            item.widget().setParent(None)

        self.mainLayout.update()
        self.count = 0


    def setConfig(self, config):
        self.config = config
        self.clearAllRows()
        for topic in self.config.getTopics():
            topic['id'] = self.count
            self.addTopicRow(topic['name'], topic['type'], topic['opType'])
コード例 #17
0
ファイル: main.py プロジェクト: reem-codes/pnu_news
class GUI(QWidget):
    # instance variable

    OUTPUT_PATH = folder = os.path.expanduser(
        '~{}Pictures{}pnu-newsletter'.format(os.path.sep, os.path.sep))

    def __init__(self):
        super().__init__()
        self.init_ui()
        self.filenames = []
        self.imgs = []

    def init_ui(self):
        """
        layout:
            1. uploading: image that could be clicked
            2. input_details: grid layout
            3. output_details: grid layout
            4. start: a button to start the image processing
        """
        self.start_process()

        uploading_image = QPixmap('image/drag-drop-file.png')
        uploading_label = QLabel(self)
        uploading_label.setPixmap(uploading_image)

        self.input_details = QVBoxLayout()

        output_details = QGridLayout()
        path_label = QLabel('output path:')
        self.path = QLabel(self.OUTPUT_PATH)
        change_button = QPushButton('change')
        output_details.addWidget(path_label, 1, 0)
        output_details.addWidget(self.path, 1, 2)
        output_details.addWidget(change_button, 1, 10)

        self.start_button = QPushButton('Start!')
        self.err_message = "To start, there must be exactly 5 ads"
        self.error_label = QLabel(self.err_message)
        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignCenter)
        self.layout.addWidget(uploading_label)
        self.layout.addLayout(self.input_details)
        self.layout.addLayout(output_details)
        self.layout.addWidget(self.start_button)
        self.layout.addWidget(self.error_label)

        self.setLayout(self.layout)

        self.setAcceptDrops(True)
        self.setFixedWidth(700)

        self.show()

        uploading_label.mousePressEvent = self.load_image_folder
        change_button.clicked.connect(self.change_path)
        self.start_button.clicked.connect(self.start)
        self.start_button.setEnabled(False)
        return

    def start_process(self):
        self.process_id = str(uuid.uuid4())
        print("new process {}".format(self.process_id))
        self.setWindowTitle('PNU newsletter by reem-codes | process {}'.format(
            self.process_id))
        self.img_process_path = 'image/proc_{}/'.format(self.process_id)
        self.filenames = []
        self.imgs = []
        return

    def change_path(self):
        self.OUTPUT_PATH = str(QFileDialog.getExistingDirectory(
            self, 'choose'))
        if self.OUTPUT_PATH:
            self.path.setText(self.OUTPUT_PATH)
        return

    def load_image_folder(self, event):
        filters = "Images (*.png *.xpm *.jpg *.jpeg *.gif)"
        filenames, _ = QFileDialog.getOpenFileNames(self,
                                                    'Open file',
                                                    filter=filters)
        self.filenames.extend(filenames)
        self.load_image()
        return

    def load_image(self):

        for i in reversed(range(self.input_details.count())):
            layout = self.input_details.itemAt(i).layout()
            for j in reversed(range(layout.count())):
                layout.itemAt(j).widget().setParent(None)
            self.input_details.removeItem(layout)

        for x in range(len(self.filenames)):
            img_detail = dict()
            img_id = str(uuid.uuid4())[:8]
            f = self.filenames[x]
            head, filename = ntpath.split(f)
            fn, ext = os.path.splitext(filename)
            img_detail['img_id'] = img_id
            img_detail['ext'] = ext
            img_detail['path'] = os.path.abspath(self.img_process_path)
            img_detail['filepath'] = os.path.abspath(
                self.img_process_path) + '/' + img_id + ext
            self.imgs.append(img_detail)

            newpath = os.path.abspath(self.img_process_path)
            if not os.path.exists(newpath):
                os.makedirs(newpath)
            # shutil.copy2(f, os.path.abspath(self.img_process_path))
            shutil.copy(f, img_detail['filepath'])

            pixmap = QPixmap(f)
            pixmap = pixmap.scaled(50, 50, Qt.KeepAspectRatio)
            label = QLabel()
            label.setPixmap(pixmap)
            filepath = QLabel(f)

            del_btn = QPushButton("x")
            del_btn.setFixedSize(25, 25)
            input = QHBoxLayout()
            input.addWidget(label)
            input.addWidget(filepath)
            input.addWidget(del_btn)
            del_btn.clicked.connect(partial(self.delete_img, img_id, input,
                                            f))  # self.delete_img

            self.input_details.addLayout(input)

        if len(self.filenames) is 5:
            self.start_button.setEnabled(True)
        else:
            self.start_button.setEnabled(False)
            self.error_label.setText(self.err_message)
        return

    def delete_img(self, img_id, layout, f):
        for i in range(len(self.imgs)):
            if img_id is self.imgs[i]['img_id']:
                x = i
        img_pth = self.img_process_path + img_id
        if os.path.exists(img_pth):
            os.remove(img_pth)

        for i in reversed(range(layout.count())):
            layout.itemAt(i).widget().setParent(None)

        self.input_details.removeItem(layout)
        self.filenames.remove(f)
        self.imgs.pop(x)

        if len(self.filenames) is 5:
            self.start_button.setEnabled(True)
        else:
            self.start_button.setEnabled(False)
            self.error_label.setText(self.err_message)
        return

    def dragEnterEvent(self, e):
        if e.mimeData().hasUrls:
            e.accept()
        else:
            e.ignore()
        return

    def dragMoveEvent(self, e):
        if e.mimeData().hasUrls:
            e.accept()
        else:
            e.ignore()
        return

    def dropEvent(self, e):
        if e.mimeData().hasUrls:
            e.setDropAction(Qt.CopyAction)
            e.accept()
            print(self.filenames)
            for url in e.mimeData().urls():
                self.filenames.append(str(url.toLocalFile()))
            print(self.filenames)

            self.load_image()
        else:
            e.ignore()
        return

    def start(self):
        imgp.main(self.path.text(), self.imgs, self.process_id)
        self.error_label.setText('process {} is Done :D'.format(
            self.process_id))
        if os.path.exists(self.img_process_path):
            shutil.rmtree(self.img_process_path)
        for i in reversed(range(self.input_details.count())):
            layout = self.input_details.itemAt(i).layout()
            for j in reversed(range(layout.count())):
                layout.itemAt(j).widget().setParent(None)
            self.input_details.removeItem(layout)
        self.start_process()
        return

    def keyPressEvent(self, e):

        if e.key() == Qt.Key_Escape:
            self.close()
        if e.key() == (Qt.Key_Enter or Qt.Key_Space):
            self.start()
        return

    def closeEvent(self, event):
        if os.path.exists(self.img_process_path):
            shutil.rmtree(self.img_process_path)
        return
コード例 #18
0
class TopicsTab(QWidget):
    configChanged = pyqtSignal()

    def __init__(self):
        super(QWidget, self).__init__()
        self.config = None
        self.count = 0
        self.topicRows = {}

        self.nameEdit = QLineEdit()
        self.dataTypeComboBox = QComboBox()
        self.fillDataTypes()
        self.opTypeComboBox = QComboBox()
        self.opTypeComboBox.addItem('sub', 'Subscribe')
        self.opTypeComboBox.addItem('pub', 'Publish')
        self.addButton = QPushButton('Add')
        self.addButton.clicked.connect(self.addClicked)

        self.mainLayout = QVBoxLayout()
        rowLayout = QHBoxLayout()
        rowLayout.addWidget(self.nameEdit)
        rowLayout.addWidget(self.dataTypeComboBox)
        rowLayout.addWidget(self.opTypeComboBox)
        rowLayout.addWidget(self.addButton)
        rowContainer = QWidget()
        rowContainer.setLayout(rowLayout)
        rowContainer.setObjectName('titleRow')
        self.mainLayout.addWidget(rowContainer)
        self.setLayout(self.mainLayout)

    def fillDataTypes(self):
        rosTypes = Interfaces.getRosMessageTypes()
        for type in rosTypes:
            concatType = type['typeDir'] + '/' + type['type']
            self.dataTypeComboBox.addItem(concatType, concatType)

    def addTopicRow(self, name, type, opType):
        rowLayout = QHBoxLayout()
        rowLayout.addWidget(QLabel(name))
        rowLayout.addWidget(QLabel(type))
        rowLayout.addWidget(QLabel(opType))
        removeButton = QPushButton('Remove')
        removeButton.clicked.connect(self.removeTopicClicked)
        removeButton.setObjectName(str(self.count))
        rowLayout.addWidget(removeButton)
        rowContainer = QWidget()
        rowContainer.setLayout(rowLayout)
        rowContainer.setObjectName('row' + str(self.count))
        self.mainLayout.addWidget(rowContainer)
        self.topicRows[self.count] = rowContainer
        self.count += 1

    def addClicked(self):
        if self.config is not None:
            self.config.addTopic(self.count, self.nameEdit.text(),
                                 self.dataTypeComboBox.currentData(),
                                 self.opTypeComboBox.currentData())
            self.addTopicRow(self.nameEdit.text(),
                             self.dataTypeComboBox.currentData(),
                             self.opTypeComboBox.currentData())
            self.nameEdit.setText('')
            self.configChanged.emit()

    def removeTopicClicked(self):
        if self.config is not None:
            itemToRemove = None
            for i in range(self.mainLayout.count()):
                if self.mainLayout.itemAt(i).widget().objectName(
                ) == 'row' + self.sender().objectName():
                    itemToRemove = self.mainLayout.itemAt(i)
                    break
            if itemToRemove is not None:
                self.mainLayout.removeItem(itemToRemove)
                itemToRemove.widget().setParent(None)
                self.mainLayout.update()
                self.configChanged.emit()
            self.config.removeTopic(int(self.sender().objectName()))
            del self.topicRows[int(self.sender().objectName())]

    def clearAllRows(self):
        clearList = []
        for i in range(self.mainLayout.count()):
            item = self.mainLayout.itemAt(i)
            if item.widget().objectName() != 'titleRow':
                clearList.append(item)

        for item in clearList:
            self.mainLayout.removeItem(item)
            item.widget().setParent(None)

        self.mainLayout.update()
        self.count = 0

    def setConfig(self, config):
        self.config = config
        self.clearAllRows()
        for topic in self.config.getTopics():
            topic['id'] = self.count
            self.addTopicRow(topic['name'], topic['type'], topic['opType'])
コード例 #19
0
class GUI(QWidget):
    def __init__(self):
        super().__init__()

        try:
            urlopen('http://maia.usno.navy.mil/ser7/finals2000A.all')
        except HTTPError as e:
            print("Main IERS link not working, using mirror")
            iers.conf.iers_auto_url = 'http://toshi.nofs.navy.mil/ser7/finals2000A.all'
        except URLError as e:
            print("Main IERS link not working, using mirror")
            iers.conf.iers_auto_url = 'http://toshi.nofs.navy.mil/ser7/finals2000A.all'

        #download_IERS_A()

        plt.style.use(astropy_mpl_style)

        irbeneLocation = EarthLocation(lat=57.5535171694 * u.deg, lon=21.8545525000 * u.deg, height=87.30 * u.m)
        self.irbene = Observer(location=irbeneLocation, name="Irbene", timezone="Europe/Riga")

        observe_time = Time(['2019-02-05 15:30:00'])

        self.targets = []
        self.targetsDict = {}
        with open("config/config.csv", "r") as csvfile:
            next(csvfile)
            reader = csv.reader(csvfile, delimiter=",", quotechar="|")
            for row in reader:
                sourceName = row[0]

                raText = row[1]
                raText = insert(raText, 'h', 2)     #Nolasa targets no faila un ievieto targetsDict un targets
                raText = insert(raText, 'm', 5)
                raText = insert(raText, 's', len(raText))

                decText = row[2]
                if (decText[0] != "-"):
                    decText = insert(decText, 'd', 2)
                    decText = insert(decText, 'm', 5)
                    decText = insert(decText, 's', len(decText))
                else:
                    decText = insert(decText, 'd', 3)
                    decText = insert(decText, 'm', 6)
                    decText = insert(decText, 's', len(decText))

                ra = Angle(raText)
                dec = Angle(decText)

                targetCoord = SkyCoord(frame='icrs', ra=ra, dec=dec, obstime="J2000")
                target = FixedTarget(coord=targetCoord, name=sourceName)
                plannedObs = PlannedObs(target, int(row[4]), int(row[3]), int(row[5]))
                self.targets.append(plannedObs)  # target / obs per_week / priority / scans per obs
                coords = {"ra": ra, "dec": dec}
                self.targetsDict[sourceName] = coords

        self.targets = sorted(self.targets, key=lambda x: x.priority)  # sort targets by priority
        self.calibrators = []
        self.calibratorsDict = {}
        with open("config/calibrators.csv", "r") as csvfile:
            next(csvfile)
            reader = csv.reader(csvfile, delimiter=";", quotechar="|")
            for row in reader:
                sourceName = row[0]

                raText = str(row[1]).replace(" ", "")
                raText = insert(raText, 'h', 2)
                raText = insert(raText, 'm', 5)
                raText = insert(raText, 's', len(raText))

                decText = str(row[2]).replace(" ", "")
                if (decText[0] != "-"):
                    decText = insert(decText, 'd', 3)
                    decText = insert(decText, 'm', 6)
                    decText = insert(decText, 's', len(decText))
                else:
                    decText = insert(decText, 'd', 3)
                    decText = insert(decText, 'm', 6)
                    decText = insert(decText, 's', len(decText))            #Nolasa no faila calibratorus un ievieto calibratorsDict un calibrators

                ra = Angle(raText)
                dec = Angle(decText)

                coords = {"ra": ra, "dec": dec}
                self.calibratorsDict[sourceName] = coords
                calibratorCoord = SkyCoord(frame='icrs', ra=ra, dec=dec, obstime="J2000")
                calibrator = FixedTarget(coord=calibratorCoord, name=sourceName)
                self.calibrators.append(calibrator)

        startArray, endArray, summaryArray = get_all_events()       #No google calendar sanem noverosanas datumus un laikus
        self.dateList = QListWidget()

        tempCheck = True
        for i in range(len(startArray)):
            dayStart = parse(startArray[i])
            dayEnd = parse(endArray[i])
            daySummary = summaryArray[i]
            daySummary = daySummary + " " + str(dayStart.date()) + " " + str(dayStart.time()) + "-" + str(dayEnd.time())
            item = QListWidgetItem(daySummary, self.dateList)
            item.setData(Qt.UserRole, [dayStart, dayEnd])               #Izveido listwidget item no datuma un laika un to ievieto listwidget
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            if tempCheck and "maser" in daySummary:
                item.setCheckState(Qt.Checked)
                tempCheck = False
            self.dateList.addItem(item)

        config = configparser.ConfigParser()
        config.read('config/config.ini')
        self.config = config._sections['Default']
        self.config['calibration'] = config['Default'].getboolean('calibration')  #Nolasa config failu


        self.layout = QGridLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0,0,0,0)
        self.setLayout(self.layout)
        self.resize(1000, 600)



        self.dateBoxList = []
        self.targetTimesCount = 0
        self.load_ui()

    def load_ui(self):   #Funkcija kas ielade galveno skatu
        self.observationList = QListWidget()
        self.plannedTargets = []
        for target in self.targets[:10]:
            item = QListWidgetItem(str(target), self.observationList)    #Aizpilda planotaju ar 10 targets kurus ieprieks nolasija no faila
            item.setData(Qt.UserRole, target)
            self.observationList.addItem(item)
            self.plannedTargets.append(target.name)

        self.layout.addWidget(self.observationList, 0, 0, 10, 2)

        self.observationList.itemSelectionChanged.connect(self.obsChanged) #Connect savieno kada UI elementa action (piemeram click) ar funkciju koda
                                                                           #Seit mainot izveleto elemntu listwidget izsauksies funkcija obsChanged
        for index in range(self.observationList.count()):
            item = self.observationList.item(index)

        self.targetLayout = QVBoxLayout()
        targetBox = QGroupBox()
        targetBox.setMaximumSize(350, 250)

        line = QHBoxLayout()
        nameLabel = QLabel("Target:")
        self.nameBox = QLineEdit()
        self.nameBox.setEnabled(False)
        nameLabel.setParent(targetBox)
        self.nameBox.setParent(targetBox)
        line.addWidget(nameLabel)
        line.addWidget(self.nameBox)
        self.targetLayout.addLayout(line)

        line = QHBoxLayout()
        priorityLabel = QLabel("Priority:")
        self.priorityBox = QLineEdit()
        priorityLabel.setParent(targetBox)
        self.priorityBox.setParent(targetBox)
        line.addWidget(priorityLabel)
        line.addWidget(self.priorityBox)
        self.targetLayout.addLayout(line)

        line = QHBoxLayout()
        obsLabel = QLabel("Obs per week:")
        self.obsBox = QLineEdit()
        obsLabel.setParent(targetBox)
        self.obsBox.setParent(targetBox)
        line.addWidget(obsLabel)
        line.addWidget(self.obsBox)
        self.targetLayout.addLayout(line)

        line = QHBoxLayout()
        scanLabel = QLabel("Scans per obs:")
        self.scanBox = QLineEdit()
        scanLabel.setParent(targetBox)
        self.scanBox.setParent(targetBox)
        line.addWidget(scanLabel)
        line.addWidget(self.scanBox)
        self.targetLayout.addLayout(line)

        line = QHBoxLayout()
        globalLabel = QLabel("Global time:")
        self.globalTimeBox = QLineEdit()
        line.addWidget(globalLabel)
        line.addWidget(self.globalTimeBox)
        self.targetLayout.addLayout(line)

        line = QHBoxLayout()
        specificLabel = QLabel("Specific times:")
        addTime = QPushButton("Add specific time")
        addTime.clicked.connect(self.add_time)
        line.addWidget(specificLabel)
        line.addWidget(addTime)
        self.targetLayout.addLayout(line)

        saveButton = QPushButton("Save changes")
        saveButton.clicked.connect(self.save_obs_changes)
        self.targetLayout.addWidget(saveButton)

        removeButton = QPushButton("Remove target")
        removeButton.clicked.connect(self.remove_obs)
        self.targetLayout.addWidget(removeButton)

        targetBox.setLayout(self.targetLayout)
        self.layout.addWidget(targetBox, 0, 2, 2, 1)

        self.targetComboBox = QComboBox()
        for key in self.targetsDict:
            if key not in self.plannedTargets:
                self.targetComboBox.addItem(key)
        self.layout.addWidget(self.targetComboBox, 2, 2)

        addButton = QPushButton("Add observation")
        addButton.clicked.connect(self.add_obs)
        self.layout.addWidget(addButton, 3, 2)

        nextButton = QPushButton("Schedule")
        nextButton.clicked.connect(self.prepare_schedule)
        self.layout.addWidget(nextButton, 0, 3)
        datesButton = QPushButton("Dates")
        datesButton.clicked.connect(self.edit_dates)
        self.layout.addWidget(datesButton, 1, 3)
        targetsButton = QPushButton("Targets")
        targetsButton.clicked.connect(self.edit_targets)
        self.layout.addWidget(targetsButton, 2, 3)
        calibratorsButton = QPushButton("Calibrators")
        calibratorsButton.clicked.connect(self.edit_calibrators)
        self.layout.addWidget(calibratorsButton, 3, 3)
        settingsButton = QPushButton("Settings")
        settingsButton.clicked.connect(self.load_settings)
        self.layout.addWidget(settingsButton, 4, 3)
        saveObsButton = QPushButton("Save observation")
        saveObsButton.clicked.connect(self.save_obs)
        self.layout.addWidget(saveObsButton, 5, 3)
        loadObsButton = QPushButton("Load observation")
        loadObsButton.clicked.connect(self.load_obs_new)
        self.layout.addWidget(loadObsButton, 6, 3)

    def add_time(self):    #Pievieno combobox ar izveletajiem datumiem
        datesChecked = 0
        for index in range(self.dateList.count()):
            if self.dateList.item(index).checkState() == Qt.Checked:
                datesChecked = datesChecked + 1
        if datesChecked > self.targetTimesCount:
            line = QHBoxLayout()
            dateBox = QComboBox()
            for index in range(self.dateList.count()):
                if self.dateList.item(index).checkState() == Qt.Checked:
                    dateBox.addItem(self.dateList.item(index).text(), self.dateList.item(index).data(Qt.UserRole))
            dateBox.addItem("Remove")
            dateBox.currentTextChanged.connect(self.timeChanged)
            self.targetTimesCount+= 1
            dateBox.sizePolicy().setHorizontalStretch(1)
            timeBox = QLineEdit()
            timeBox.sizePolicy().setHorizontalStretch(3)
            line.addWidget(dateBox)
            line.addWidget(timeBox)
            self.dateBoxList.append(line)
            self.targetLayout.insertLayout(self.targetLayout.count()-2, line)
        else:
            self.show_error("Date error", "Can't select more times than selected dates")

    def timeChanged(self, item): #Ja pie specifiskajiem laikiem izvelas remove tad iznem to
        if item == "Remove":
            for line in self.dateBoxList:
                if line is not None:
                    item = line.itemAt(0)
                    widget = item.widget()
                    if type(widget) == type(QComboBox()):
                        if widget.currentText() == "Remove":
                            break
            self.targetTimesCount -= 1
            widget.disconnect()
            self.deleteItemsOfLayout(line)
            self.targetLayout.removeItem(line)
            self.dateBoxList.remove(line)


    def obsChanged(self):  #Nomainot observation nomaina visus texta laukus
        if len(self.observationList.selectedItems()) > 0:
            item = self.observationList.currentItem()
            plannedObs = item.data(Qt.UserRole)
            self.nameBox.setText(plannedObs.name)
            self.priorityBox.setText(str(plannedObs.priority))
            self.obsBox.setText(str(plannedObs.obs_per_week))
            self.scanBox.setText(str(plannedObs.scans_per_obs))
            i = 0
            maxi = self.targetLayout.count()
            while(i < maxi):
                layout_item = self.targetLayout.itemAt(i)
                if layout_item in self.dateBoxList:
                    self.deleteItemsOfLayout(layout_item.layout())
                    self.targetLayout.removeItem(layout_item)
                    self.dateBoxList.remove(layout_item)
                    maxi = self.targetLayout.count()
                    i = i -1
                i=i+1
            self.dateBoxList.clear()
            self.targetTimesCount = 0
            if plannedObs.times:
                checkedDates = []
                for index in range(self.dateList.count()):
                    if self.dateList.item(index).checkState() == Qt.Checked:
                        checkedDates.append(self.dateList.item(index).text())
                print(checkedDates)
                for time in list(plannedObs.times):
                    print(time)
                    if time not in checkedDates:    #Ja observation pievienots specifisks laiks datumam kurs vairs netiks izmantots to pazino lietotajam
                        self.show_error("Date mismatch", "Date "+time+" is not checked, removing it")
                        plannedObs.times.remove(time)
                for time in list(plannedObs.times):
                    line = QHBoxLayout()
                    dateBox = QComboBox()
                    for index in range(self.dateList.count()):
                        if self.dateList.item(index).checkState() == Qt.Checked: #Specific laikiem pievieno tikai datumus kas izveleti pie dates
                            dateBox.addItem(self.dateList.item(index).text(), self.dateList.item(index).data(Qt.UserRole))
                    dateBox.addItem("Remove")
                    dateBox.currentTextChanged.connect(self.timeChanged)
                    self.targetTimesCount += 1
                    dateBox.sizePolicy().setHorizontalStretch(1)
                    timeBox = QLineEdit(plannedObs.times[time])
                    timeBox.sizePolicy().setHorizontalStretch(3)
                    line.addWidget(dateBox)
                    line.addWidget(timeBox)
                    self.dateBoxList.append(line)
                    self.targetLayout.insertLayout(self.targetLayout.count() - 2, line)
                    dateBox.setCurrentIndex(dateBox.findText(time))

        else:
            self.nameBox.setText("")
            self.priorityBox.setText("")
            self.obsBox.setText("")
            self.scanBox.setText("")
            self.targetTimesCount = 0

    def remove_obs(self):
        if len(self.observationList.selectedItems()) > 0:
            self.plannedTargets.remove(self.observationList.currentItem().data(Qt.UserRole).name)
            self.targetComboBox.addItem(self.observationList.currentItem().data(Qt.UserRole).name)
            self.observationList.takeItem(self.observationList.currentRow())
        else:
            self.show_error("Observation error","Select an observation to remove it")


    def save_obs_changes(self): #Ja visi teksta lauki atbilst parbaudem tad saglaba datus, ja ne tad pazino lietotajam
        if not self.priorityBox.text().isdigit():
            self.show_error("Priority error", "Priority must be from 1 to 4")
        elif int(self.priorityBox.text()) > 4 or int(self.priorityBox.text()) < 0:
            self.show_error("Priority error", "Priority must be from 1 to 4")
        elif not self.obsBox.text().isdigit():
            self.show_error("Obs error", "Obs must be from 1 to 7")
        elif int(self.obsBox.text()) > 7 or int(self.obsBox.text()) < 0:
            self.show_error("Obs error", "Obs must be from 1 to 7")
        elif not self.scanBox.text().isdigit():
            self.show_error("Scan error", "Scan must be from 1 to 120")
        elif int(self.scanBox.text()) > 120 or int(self.scanBox.text()) < 0:
            self.show_error("Scan error", "Scan must be from 1 to 120")
        elif len(self.dateBoxList) != len(set(self.dateBoxList)):
            self.show_error("Date error", "Make sure specified times don't use same dates")
        else:
            times = {}
            timeCheck = True
            for line in self.dateBoxList:
                if line.count() > 0:
                    item = line.itemAt(0)
                    widget = item.widget()
                    date = widget.currentText()
                    time = date[-17:]
                    time = time.split('-')
                    timeStart = time[0]
                    timeStart = timeStart[:-3]
                    timeEnd = time[1]
                    timeEnd = timeEnd[:-3]
                    time = line.itemAt(1).widget().text()
                    timeCheck = self.time_check(time, timeStart, timeEnd)

                    if timeCheck == False:
                        break
                    else:
                        times[date] = line.itemAt(1).widget().text()

            if timeCheck: #Ja visas parbaudes izietas tad saglaba datus
                self.observationList.currentItem().data(Qt.UserRole).times = times
                self.observationList.currentItem().data(Qt.UserRole).priority = int(self.priorityBox.text())
                self.observationList.currentItem().data(Qt.UserRole).obs_per_week = int(self.obsBox.text())
                self.observationList.currentItem().data(Qt.UserRole).scans_per_obs = int(self.scanBox.text())
                self.observationList.currentItem().data(Qt.UserRole).global_time = self.globalTimeBox.text()
                self.observationList.currentItem().setText(str(self.observationList.currentItem().data(Qt.UserRole)))
            else:
                self.show_error("Specific time error", "Make sure the specific times fit the dates selected")

    def add_obs(self): #Izveido jaunu observation
        if self.targetComboBox.count() > 0:
            targetName = self.targetComboBox.currentText()
            ra = self.targetsDict[targetName]["ra"]
            dec = self.targetsDict[targetName]["dec"]
            coord = SkyCoord(frame='icrs', ra=ra, dec=dec, obstime="J2000")
            target = FixedTarget(coord=coord, name=targetName)
            data = PlannedObs(target, 1, 1, 1)
            item = QListWidgetItem(str(data), self.observationList)
            item.setData(Qt.UserRole, data)
            self.observationList.addItem(item)
            self.plannedTargets.append(data.name)
            self.targetComboBox.removeItem(self.targetComboBox.currentIndex())

    def edit_dates(self): #Atver dates skatu
        self.clear_window()
        self.layout.addWidget(self.dateList, 0, 0, 5, 2)
        backButton = QPushButton("Back to planner")
        self.layout.addWidget(backButton, 1, 2)
        backButton.clicked.connect(self.to_start)

    def edit_targets(self): #Atver targets skatu
        self.clear_window()

        self.targetList = QListWidget()
        for key in self.targetsDict:
            self.targetList.addItem(key)
        self.targetList.itemClicked.connect(self.targetChanged)
        self.layout.addWidget(self.targetList, 0, 0, 3, 1)

        targetLayout = QGridLayout()
        targetLayout.addWidget(QLabel("Ra:"), 0, 0)
        self.raBox = QLineEdit()
        targetLayout.addWidget(self.raBox, 0, 1)
        targetLayout.addWidget(QLabel("Dec:"), 1, 0)
        self.decBox = QLineEdit()
        targetLayout.addWidget(self.decBox, 1, 1)
        self.saveButton = QPushButton("Save changes")
        self.saveButton.clicked.connect(self.save_target_changes)
        targetLayout.addWidget(self.saveButton, 2, 0, 1, 2)
        targetBox = QGroupBox()
        targetBox.setLayout(targetLayout)
        self.layout.addWidget(targetBox, 0, 1)
        self.saveButton.setEnabled(False)

        addTargetLayout = QGridLayout()
        addTargetLayout.addWidget(QLabel("Name:"), 0, 0)
        self.addNameBox = QLineEdit()
        addTargetLayout.addWidget(self.addNameBox, 0, 1)

        addTargetLayout.addWidget(QLabel("Ra:"), 1, 0)
        self.addRaBox = QLineEdit()
        addTargetLayout.addWidget(self.addRaBox, 1, 1)

        addTargetLayout.addWidget(QLabel("Dec:"), 2, 0)
        self.addDecBox = QLineEdit()
        addTargetLayout.addWidget(self.addDecBox, 2, 1)

        self.addSaveButton = QPushButton("Save changes")
        self.addSaveButton.clicked.connect(self.add_target)
        addTargetLayout.addWidget(self.addSaveButton, 3, 0, 1, 2)

        addTargetBox = QGroupBox()
        addTargetBox.setLayout(addTargetLayout)
        self.layout.addWidget(addTargetBox, 1, 1)

        backButton = QPushButton("Back to planner")
        self.layout.addWidget(backButton, 0, 3)
        backButton.clicked.connect(self.to_start)

    def targetChanged(self, item):
        if not self.saveButton.isEnabled():
            self.saveButton.setEnabled(True)
        targetName = item.text()
        target = self.targetsDict[targetName]
        self.raBox.setText(target["ra"].to_string())
        self.decBox.setText(target["dec"].to_string(unit=u.degree))

    def save_target_changes(self):
        if len(self.targetList.selectedItems()) != 1:
            self.show_error("Target error", "Make sure you have selected only 1 target")
        else:
            targetName = self.targetList.selectedItems()[0].text()
            raPattern = re.compile("[0-9]{1,2}h[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,3})?s")
            decPattern = re.compile("-?[0-9]{1,2}d[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,3})?s")
            ra = self.raBox.text()
            dec = self.decBox.text()
            if not raPattern.match(ra):
                self.show_error("Ra error", "Ra coordinates don't match pattern 00h00m00.00s")
            elif not decPattern.match(dec):
                self.show_error("Dec error", "Dec coordinates don't match pattern 00d00m00.00s")
            else:
                self.targetsDict[targetName]["ra"] = Angle(ra)
                self.targetsDict[targetName]["dec"] = Angle(dec)

    def add_target(self): #Pievieno jaunu target
        raPattern = re.compile("[0-9]{1,2}h[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,3})?s")
        decPattern = re.compile("-?[0-9]{1,2}d[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,3})?s")
        ra = self.addRaBox.text()
        dec = self.addDecBox.text()
        name = self.addNameBox.text()
        print(self.targetsDict.keys())
        if ra == "" or dec == "" or name == "":
            self.show_error("Empty box", "Please fill all boxes")
        elif name in self.targetsDict.keys():
            self.show_error("Existing target", "Target already exists, please edit it")
        elif not raPattern.match(ra):
            self.show_error("Ra error", "Ra coordinates don't match pattern 00h00m00.00s")
        elif not decPattern.match(dec):
            self.show_error("Dec error", "Dec coordinates don't match pattern 00d00m00.00s")
        else:
            self.targetsDict[name] = {}
            self.targetsDict[name]["ra"] = Angle(ra)
            self.targetsDict[name]["dec"] = Angle(dec)
            self.edit_targets()

    def edit_calibrators(self): #Atver calibrators skatu
        self.clear_window()

        self.calibratorList = QListWidget()
        for key in self.calibratorsDict:
            self.calibratorList.addItem(key)
        self.calibratorList.itemClicked.connect(self.calibratorChanged)
        self.layout.addWidget(self.calibratorList, 0, 0, 3, 1)

        calibratorLayout = QGridLayout()
        calibratorLayout.addWidget(QLabel("Ra:"), 0, 0)
        self.raBox = QLineEdit()
        calibratorLayout.addWidget(self.raBox, 0, 1)
        calibratorLayout.addWidget(QLabel("Dec:"), 1, 0)
        self.decBox = QLineEdit()
        calibratorLayout.addWidget(self.decBox, 1, 1)
        self.saveButton = QPushButton("Save changes")
        self.saveButton.clicked.connect(self.save_calibrator_changes)
        calibratorLayout.addWidget(self.saveButton, 2, 0, 1, 2)
        calibratorBox = QGroupBox()
        calibratorBox.setLayout(calibratorLayout)
        self.layout.addWidget(calibratorBox, 0, 1)
        self.saveButton.setEnabled(False)

        addcalibratorLayout = QGridLayout()
        addcalibratorLayout.addWidget(QLabel("Name:"), 0, 0)
        self.addNameBox = QLineEdit()
        addcalibratorLayout.addWidget(self.addNameBox, 0, 1)

        addcalibratorLayout.addWidget(QLabel("Ra:"), 1, 0)
        self.addRaBox = QLineEdit()
        addcalibratorLayout.addWidget(self.addRaBox, 1, 1)

        addcalibratorLayout.addWidget(QLabel("Dec:"), 2, 0)
        self.addDecBox = QLineEdit()
        addcalibratorLayout.addWidget(self.addDecBox, 2, 1)

        self.addSaveButton = QPushButton("Save changes")
        self.addSaveButton.clicked.connect(self.add_calibrator)
        addcalibratorLayout.addWidget(self.addSaveButton, 3, 0, 1, 2)

        addcalibratorBox = QGroupBox()
        addcalibratorBox.setLayout(addcalibratorLayout)
        self.layout.addWidget(addcalibratorBox, 1, 1)

        backButton = QPushButton("Back to planner")
        self.layout.addWidget(backButton, 0, 3)
        backButton.clicked.connect(self.to_start)

    def calibratorChanged(self, item):
        if not self.saveButton.isEnabled():
            self.saveButton.setEnabled(True)
        calibratorName = item.text()
        calibrator = self.calibratorsDict[calibratorName]
        self.raBox.setText(calibrator["ra"].to_string())
        self.decBox.setText(calibrator["dec"].to_string(unit=u.degree))

    def save_calibrator_changes(self):
        if len(self.calibratorList.selectedItems()) != 1:
            self.show_error("calibrator error", "Make sure you have selected only 1 calibrator")
        else:
            calibratorName = self.calibratorList.selectedItems()[0].text()
            raPattern = re.compile("[0-9]{1,2}h[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,5})?s")
            decPattern = re.compile("-?[0-9]{1,2}d[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,5})?s")
            ra = self.raBox.text()
            dec = self.decBox.text()
            if not raPattern.match(ra):
                self.show_error("Ra error", "Ra coordinates don't match pattern 00h00m00.00s")
            elif not decPattern.match(dec):
                self.show_error("Dec error", "Dec coordinates don't match pattern 00d00m00.00s")
            else:
                self.calibratorsDict[calibratorName]["ra"] = Angle(ra)
                self.calibratorsDict[calibratorName]["dec"] = Angle(dec)

    def add_calibrator(self):
        raPattern = re.compile("[0-9]{1,2}h[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,5})?s")
        decPattern = re.compile("-?[0-9]{1,2}d[0-9]{1,2}m[0-9]{1,2}(\.[0-9]{1,5})?s")
        ra = self.addRaBox.text()
        dec = self.addDecBox.text()
        name = self.addNameBox.text()
        print(self.calibratorsDict.keys())
        if ra == "" or dec == "" or name == "":
            self.show_error("Empty box", "Please fill all boxes")
        elif name in self.calibratorsDict.keys():
            self.show_error("Existing calibrator", "calibrator already exists, please edit it")
        elif not raPattern.match(ra):
            self.show_error("Ra error", "Ra coordinates don't match pattern 00h00m00.00s")
        elif not decPattern.match(dec):
            self.show_error("Dec error", "Dec coordinates don't match pattern 00d00m00.00s")
        else:
            self.calibratorsDict[name] = {}
            self.calibratorsDict[name]["ra"] = Angle(ra)
            self.calibratorsDict[name]["dec"] = Angle(dec)
            self.edit_calibrators()


    def load_settings(self): #Atver settings skatu
        self.clear_window()
        targetLayout = QFormLayout()
        targetBox = QGroupBox()
        targetBox.setMaximumSize(350, 250)

        calibLabel = QLabel("Calib every X min:")
        self.calibBox = QLineEdit()
        calibLabel.setParent(targetBox)
        self.calibBox.setParent(targetBox)
        self.calibBox.setText(self.config['maxtimewithoutcalibration'])
        targetLayout.addRow(calibLabel, self.calibBox)

        calibDurLabel = QLabel("Calib duration:")
        self.calibDurBox = QLineEdit()
        calibDurLabel.setParent(targetBox)
        self.calibDurBox.setParent(targetBox)
        self.calibDurBox.setText(self.config['calibrationlength'])
        targetLayout.addRow(calibDurLabel, self.calibDurBox)

        minAltLabel = QLabel("Min alt:")
        self.minAltBox = QLineEdit()
        minAltLabel.setParent(targetBox)
        self.minAltBox.setParent(targetBox)
        self.minAltBox.setText(self.config['minaltitude'])
        targetLayout.addRow(minAltLabel, self.minAltBox)

        maxAltLabel = QLabel("Max alt:")
        self.maxAltBox = QLineEdit()
        maxAltLabel.setParent(targetBox)
        self.maxAltBox.setParent(targetBox)
        self.maxAltBox.setText(self.config['maxaltitude'])
        targetLayout.addRow(maxAltLabel, self.maxAltBox)

        calibToggleLabel = QLabel("Calibration on/off")
        self.calibCheckBox = QCheckBox()
        calibToggleLabel.setParent(targetBox)
        self.calibCheckBox.setParent(targetBox)
        if (self.config['calibration']):
            self.calibCheckBox.setChecked(True)
        else:
            self.calibCheckBox.setChecked(False)
        targetLayout.addRow(calibToggleLabel, self.calibCheckBox)

        saveButton = QPushButton("Save settings")
        saveButton.clicked.connect(self.save_settings)
        targetLayout.addRow(saveButton)

        targetBox.setLayout(targetLayout)
        self.layout.addWidget(targetBox, 0, 2, 2, 1)

    def save_settings(self):
        if not (self.calibBox.text().isdigit() and int(self.calibBox.text()) > 0):
            self.show_error("Input error","Max time without calib must be positive number")
        elif not (self.calibDurBox.text().isdigit() and int(self.calibDurBox.text()) > 0):
            self.show_error("Input error","Calib duration must be positive number")
        elif not (self.minAltBox.text().isdigit() and int(self.minAltBox.text()) > 0):
            self.show_error("Input error","Min alt must be positive number")
        elif not (self.maxAltBox.text().isdigit() and int(self.maxAltBox.text()) > 0):
            self.show_error("Input error","Max alt must be positive number")
        else:
            self.config['maxtimewithoutcalibration'] = self.calibBox.text()
            self.config['calibrationlength'] = self.calibDurBox.text()
            self.config['minaltitude'] = self.minAltBox.text()
            self.config['maxaltitude'] = self.maxAltBox.text()
            self.config['calibration'] = self.calibCheckBox.isChecked()
            self.to_start()

    def prepare_schedule(self): #Pirms uzsak planosanu, parbauda vai ir izvelets kads datums
        hasDate = False
        for index in range(self.dateList.count()):
            if self.dateList.item(index).checkState() == Qt.Checked:
                hasDate = True
                break
        if not hasDate:
            self.show_error("Date error", "No dates selected for schedule")
        else:
            self.start_schedule()

    def start_schedule(self): #Sak planosanu
        items = (self.layout.itemAt(i).widget() for i in range(self.layout.count()))
        self.targets = []

        for index in range(self.observationList.count()):
            item = self.observationList.item(index)
            target = item.data(Qt.UserRole)
            self.targets.append(target)  #Visus obs ievieto masiva targets

        targ_to_color = {}
        color_idx = np.linspace(0, 1, len(self.targets))

        for target, ci in zip(set(self.targets), color_idx): #Katram target un calibrator pieskir savu krasu
            if "split" not in target.name:
                if target.name not in targ_to_color:
                    targ_to_color[target.name] = plt.cm.jet(ci)

        calib_to_color = {}
        color_idx = np.linspace(0, 1, len(self.calibrators))

        for calibrator, ci in zip(set(self.calibrators), color_idx):
            if "split" not in calibrator.name:
                if calibrator.name not in calib_to_color:
                    calib_to_color[calibrator.name] = plt.cm.brg(ci)

        self.plots_idx = 0
        self.plots = []

        week = {}

        for index in range(self.dateList.count()):
            if self.dateList.item(index).checkState() == Qt.Checked: #Dates ievieto dict week
                week[self.dateList.item(index).text()]=[self.dateList.item(index).data(Qt.UserRole)[0], self.dateList.item(index).data(Qt.UserRole)[1]]


        for daySummary, day in week.items():

            dayStart = Time(day[0])  # convert from datetime to astropy.time
            dayEnd = Time(day[1])

            timeDict = {}

            for target in self.targets:
                if daySummary in target.times:
                    timeDict[target.name] = target.times[daySummary] #Pievieno specifiskos laikus dict timeDict
                elif target.global_time != "":
                    timeDict[target.name] = target.global_time

            minalt = self.config['minaltitude']
            maxalt = self.config['maxaltitude']

            constraints = [AltitudeConstraint(minalt * u.deg, maxalt * u.deg)]

            read_out = 1 * u.second
            target_exp = 60 * u.second
            blocks = []

            for target in self.targets:
                n = target.scans_per_obs
                priority = target.priority
                if (target.obs_per_week != 0): #Ja observation vel ir janovero tad izveido ObservingBlock
                    b = ObservingBlock.from_exposures(target.target, priority, target_exp, n, read_out)
                    blocks.append(b)


            slew_rate = 2 * u.deg / u.second
            transitioner = Transitioner(slew_rate, {'filter': {'default': 5 * u.second}})

            if (self.config['calibration']): #Padod mainigos planotajam
                prior_scheduler = SequentialScheduler(constraints=constraints, observer=self.irbene, transitioner=transitioner,
                                                      calibrators=self.calibrators, config=self.config, timeDict=timeDict)

                priority_schedule = Schedule(dayStart, dayEnd, targColor=targ_to_color, calibColor=calib_to_color, minalt=minalt, maxalt=maxalt)
            else:
                prior_scheduler = SequentialScheduler(constraints=constraints, observer=self.irbene,
                                                      transitioner=transitioner,
                                                      config=self.config, timeDict=timeDict)

                priority_schedule = Schedule(dayStart, dayEnd, targColor=targ_to_color, minalt=minalt, maxalt=maxalt)

            prior_scheduler(blocks, priority_schedule)

            observations = []
            for block in priority_schedule.scheduled_blocks:
                if hasattr(block, 'target'):
                    observation = Observation(block.target.name, block.start_time.datetime,
                                              (block.start_time + block.duration).datetime)
                    observations.append(observation)

            dict_array = []
            for observation in observations: #Saplanotos block nolasa un ieraksta faila
                for target in self.targets:
                    if target.name == observation.name:
                        print(target.name, " has been observed once")
                        target.obs_per_week -= 1
                dict_array.append({
                    "obs_name": observation.name,
                    "start_time": observation.start_time.strftime("%Y-%m-%d %H:%M:%S"),
                    "end_time": observation.end_time.strftime("%Y-%m-%d %H:%M:%S"),
                })

            json_dict = dict()
            json_dict["observations"] = dict_array
            if not os.path.isdir("observations"):
                os.mkdir("observations")
            if not os.path.isdir("observations/"):
                os.mkdir("observations")
            with open("observations/" + day[0].strftime("%Y-%m-%d-%H-%M") + ".json", 'w') as outfile:
                json.dump(json_dict, outfile, indent=4)


            sky = Plot() #Izveido grafikus
            skyCheck = sky.plot_sky_schedule(priority_schedule)
            alt = Plot(width=6)
            alt.plot_altitude_schedule(priority_schedule)

            if skyCheck is not False:
                self.plots.append([sky, alt])
            else:
                self.show_error("Empty schedule", "Schedule "+daySummary+"removing it")

        timeLeft = 0
        for target in self.targets:
            timeLeft += target.obs_per_week * target.scans_per_obs
            print(target.name, ' observations left ', target.obs_per_week, ' scan size ', target.scans_per_obs, ' priority ', target.priority)
        print('Total time left to observe ', timeLeft)

        self.showSky = False
        self.showAlt = False
        self.showBoth = True

        self.show_schedule()

    def show_schedule(self): #Atver grafiku skatu
        self.clear_window()

        sky, alt = self.plots[self.plots_idx]

        if self.showSky:
            self.layout.addWidget(sky, 0, 0, 2, 6)

        elif self.showAlt:
            self.layout.addWidget(alt, 0, 0, 2, 6)

        elif self.showBoth:
            self.layout.addWidget(sky, 0, 0, 1, 6)
            self.layout.addWidget(alt, 1, 0, 1, 6)

        self.toolbar = NavigationToolbar(alt, alt.parent)
        self.layout.addWidget(self.toolbar, 2, 0, 1, 3)

        self.radioSky = QRadioButton("Show skychart")
        self.radioAlt = QRadioButton("Show altitude")
        self.radioBoth = QRadioButton("Show both")

        self.radioSky.clicked.connect(self.changeScheduleView)
        self.radioAlt.clicked.connect(self.changeScheduleView)
        self.radioBoth.clicked.connect(self.changeScheduleView)


        self.layout.addWidget(self.radioSky, 2, 3)
        self.layout.addWidget(self.radioAlt, 2, 4)
        self.layout.addWidget(self.radioBoth, 2, 5)

        nextButton = QPushButton("Next")
        nextButton.clicked.connect(self.next_schedule)
        backButton = QPushButton("Back")
        backButton.clicked.connect(self.back_schedule)
        self.layout.addWidget(backButton, 3, 0, 1, 3)
        self.layout.addWidget(nextButton, 3, 3, 1, 3)

        startButton = QPushButton("To start")
        startButton.clicked.connect(self.to_start)
        self.layout.addWidget(startButton, 4, 0, 1, 3)

        if self.plots_idx == 0:
            backButton.hide()
        if self.plots_idx == (len(self.plots) - 1):
            nextButton.hide()

    def next_schedule(self):
        self.plots_idx += 1
        self.show_schedule()

    def changeScheduleView(self):
        radioText = self.sender().text()
        if "sky" in radioText:
            self.showSky = True
            self.showAlt = False
            self.showBoth = False
            self.show_schedule()
            self.radioSky.setChecked(True)
        elif "alt" in radioText:
            self.showSky = False
            self.showAlt = True
            self.showBoth = False
            self.show_schedule()
            self.radioAlt.setChecked(True)
        elif "both" in radioText:
            self.showSky = False
            self.showAlt = False
            self.showBoth = True
            self.show_schedule()
            self.radioBoth.setChecked(True)

    def back_schedule(self):
        self.plots_idx -= 1
        self.show_schedule()

    def save_obs(self):
        filename = self.saveFileDialog()
        if filename != "Fail":
            obsList = [self.observationList.item(i).data(Qt.UserRole) for i in range(self.observationList.count())]
            json_dict = dict()
            for obs in obsList:
                json_dict[obs.target.name]={
                    "priority": obs.priority,
                    "obs_per_week": obs.obs_per_week,
                    "scans_per_obs": obs.scans_per_obs,
                    "global_time": obs.global_time,
                    "times": obs.times,
                }
            print(json_dict)
            with open(filename, 'w') as outfile:
                json.dump(json_dict, outfile, indent=4)


    def saveFileDialog(self):
        save = QFileDialog()
        save.setDefaultSuffix(".json")
        save.setNameFilter("JSON files (*.json)")
        save.setAcceptMode(QFileDialog.AcceptSave)
        save.setOption(QFileDialog.DontUseNativeDialog)
        if save.exec_() == QFileDialog.Accepted:
            return save.selectedFiles()[0]
        else:
            return "Fail"

    def load_obs(self):
        load = QFileDialog()
        load.setDefaultSuffix(".json")
        load.setNameFilter("JSON files (*.json)")
        load.setAcceptMode(QFileDialog.AcceptOpen)
        load.setOption(QFileDialog.DontUseNativeDialog)
        if load.exec_() == QFileDialog.Accepted:
            filename = load.selectedFiles()[0]
            with open(filename) as json_file:
                obs_dict = json.load(json_file)
                self.observationList.clear()
                for key in obs_dict:
                    if key in self.targetsDict:
                        targetName = key
                        ra = self.targetsDict[targetName]["ra"]
                        dec = self.targetsDict[targetName]["dec"]
                        coord = SkyCoord(frame='icrs', ra=ra, dec=dec, obstime="J2000")
                        target = FixedTarget(coord=coord, name=targetName)
                        for date in obs_dict[key]['times']:
                            print(date)

                            # TODO Te pielikt date parbaudes, vai atkekset ja ir vai iznemt ja nav

                        data = PlannedObs(target, int(obs_dict[key]['priority']), int(obs_dict[key]['obs_per_week']),
                                          int(obs_dict[key]['scans_per_obs']), obs_dict[key]['times'],
                                          obs_dict[key]['global_time'])
                        item = QListWidgetItem(str(data), self.observationList)
                        item.setData(Qt.UserRole, data)
                        self.observationList.addItem(item)
                        self.plannedTargets.append(target.name)
                    else:
                        self.show_error("Target error", key + " not in targets, skipping it")
        else:
            print("Something went wrong")

    def load_obs_new(self):
        load = QFileDialog()
        load.setDefaultSuffix(".conf")
        load.setNameFilter("CONF files (*.conf)")
        load.setAcceptMode(QFileDialog.AcceptOpen)
        load.setOption(QFileDialog.DontUseNativeDialog)
        if load.exec_() == QFileDialog.Accepted:
            self.observationList.clear()
            filename = load.selectedFiles()[0]
            configObs = configparser.ConfigParser()
            configObs.read(filename)
            sections = configObs.sections()
            for section in sections:
                target = section.split('_')[0]
                ra = configObs[section]["RA"]
                dec = configObs[section]["DEC"]

                if target not in self.targetsDict.keys():
                    coords = {"ra": Angle(ra), "dec": Angle(dec)}
                    self.targetsDict[target] = coords
                else:
                    if Angle(ra) != Angle(self.targetsDict[target]["ra"]) or Angle(dec) != Angle(self.targetsDict[target]["dec"]):
                        qm = QMessageBox
                        ret = qm.question(self,'', target+" has different coords in the load file, would you like to overwrite the current ones?\n"+
                                                            "new coords:"+str(ra)+";   "+str(dec)+"\ncurrent coords:"+str(self.targetsDict[target]["ra"])+";   "+str(self.targetsDict[target]["dec"]), qm.Yes | qm.No)
                        if ret == qm.Yes:
                            self.targetsDict[target]["ra"] = Angle(ra)
                            self.targetsDict[target]["dec"] = Angle(dec)

                targetName = target
                ra = self.targetsDict[targetName]["ra"]
                dec = self.targetsDict[targetName]["dec"]
                coord = SkyCoord(frame='icrs', ra=ra, dec=dec, obstime="J2000")
                target = FixedTarget(coord=coord, name=targetName)

                data = PlannedObs(target, 1, 1, int(configObs[section]["n_scans"]), None, None)
                item = QListWidgetItem(str(data), self.observationList)
                item.setData(Qt.UserRole, data)
                self.observationList.addItem(item)
                self.plannedTargets.append(target.name)

        else:
            print("Something went wrong")


    def show_error(self, title, error_message):
        error_dialog = QMessageBox.critical(self, title, error_message)

    def to_start(self):
        self.clear_window()
        self.load_ui()

    def clear_window(self):
        for i in reversed(range(self.layout.count())):
            self.layout.itemAt(i).widget().setParent(None)

    def is_time_format(self, string):
        p = re.compile('^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$')
        print(string)
        res = bool(p.match(string))
        return res

    def time_check(self, time, timeStart, timeEnd):
        if not self.is_time_format(time):
            return False
        else:
            time = time.split(':')
            timeStart = timeStart.split(':')
            timeEnd = timeEnd.split(':')
            if int(time[0]) < int(timeStart[0]) or int(time[0]) > int(timeEnd[0]):
                return False
            elif int(time[0]) > int(timeStart[0]) and int(time[0]) < int(timeEnd[0]):
                return True
            elif (int(time[0]) == int(timeStart[0]) and int(time[1]) < int(timeStart[1])) or (int(time[0]) == int(timeEnd[0]) and int(time[1]) > int(timeEnd[1])):
                return False
            elif (int(time[0]) == int(timeStart[0]) and int(time[1]) >= int(timeStart[1])) or (int(time[0]) == int(timeEnd[0]) and int(time[1]) < int(timeEnd[1])):
                return True

    def deleteItemsOfLayout(self, layout):
        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                widget = item.widget()
                if widget is not None:
                    widget.setParent(None)
                else:
                    self.deleteItemsOfLayout(item.layout())
コード例 #20
0
class HtmlTranslator(QtWidgets.QMainWindow, tabs_design.Ui_MainWindow):
    def initTableHeader(self):
        # Шапка таблицы
        GUI.setTableHeader(self.langs, self.tableHeaderLayout)

    ################------------------------####################
    #############**Создаем индексы переводов**##################
    ################------------------------####################
    def indexVocabulary(self):
        initData = self.initDataVocabulary
        # Инициализация списков для дальнейшего наполнения
        data = {}
        for lang in self.langs:
            data[lang] = {}
        # Формируем необходимую структуру данных для записи в индексные файлы
        for key in initData:
            for lang in self.langs:
                data[lang].update({initData[key][lang]: key})
        # Пишем в файл json данные формата "значение : ключ" (с учетом локализации)
        for lng in data:
            self.writeJson(self.vocabularyFileName + '_' + lng, data[lng])

    ################------------------------####################
    #############*****Заппись json в файл*****##################
    ################------------------------####################
    def writeJson(self, fileName, data):
        with open(fileName + '.json', 'w', encoding='utf8') as f:
            json.dump(data, f, ensure_ascii=False, indent=4)

    ################------------------------####################
    #############****Инициализация словаря****##################
    ################------------------------####################
    def initVocabulary(self):
        layout = QGridLayout()
        initData = self.initDataVocabulary
        widget = QWidget()
        # Виджет в скролл области
        self.scrollArea.setWidget(widget)
        self.vocabularyLayout = QVBoxLayout(widget)

        # Рендер переводов
        for key in initData:
            horizontal = GUI.setRow(self, self.langs, initData[key], key,
                                    self.vocabularyLayout)
            # Установка обработчиков нажатия кнопок
            for itemInRow in range(horizontal.itemAt(0).count()):
                widgetType = horizontal.itemAt(0).itemAt(
                    itemInRow).widget().property('type')
                if (widgetType == 'edit'):
                    horizontal.itemAt(0).itemAt(
                        itemInRow).widget().clicked.connect(self.editClick)
                if (widgetType == 'delete'):
                    horizontal.itemAt(0).itemAt(
                        itemInRow).widget().clicked.connect(self.deleteClick)
            self.vocabularyLayout.addLayout(horizontal)
        # Устанавливаем основной (вертикальный шаблон) в окне приложения
        self.vocabularyLayout.addStretch(1)

    def deleteClick(self):
        # Подтверждение удаления записи
        confirmDelete = QtWidgets.QMessageBox.critical(
            None, 'Подтверждение удаления',
            'Вы действительно желаете удалить данную запись?',
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if confirmDelete == QtWidgets.QMessageBox.Yes:
            # Получаем индекс горизонтального шаблона по аттрибуту кнопки (ID)
            horizontalRowLayoutId = self.sender().property('id')
            keyAttr = self.sender().property('key')
            horizontalRowLayout = self.vocabularyLayout.itemAt(
                horizontalRowLayoutId)

            # Шаблон сетки в горизонтальном шаблоне (QGridLayoiut в шаблоне QHLayout)
            innerRowGridLayout = horizontalRowLayout.itemAt(
                0
            )  #Немного костыль, если будет боолее одного layout-та не сработает
            widgetCount = innerRowGridLayout.count()

            # Удаляем все виджеты в шаблоне (layuot-e)
            for i in reversed(range(widgetCount)):
                innerRowGridLayout.itemAt(i).widget().setParent(None)
            # Удаляем шаблон сетки (QGridLayout) из горизонтального шаблона
            horizontalRowLayout.removeItem(horizontalRowLayout.itemAt(0))
            self.vocabularyLayout.removeItem(
                self.vocabularyLayout.itemAt(horizontalRowLayoutId))

            #Обновление аттрибутов ID у кнопок редактирования и удаления (чтобы индексы слоев GUI соответствовали индексам записей из словаря)
            i = 0
            for horizontalRow in range(
                    self.vocabularyLayout.count() - 1
            ):  # count()-1 Убираем из общего количества объектов последний добавляющий растяжение макету (self.vocabularyLayout.addStretch(1))
                if (self.vocabularyLayout.itemAt(horizontalRow).itemAt(0) !=
                        None):
                    for itemInRow in range(
                            self.vocabularyLayout.itemAt(horizontalRow).itemAt(
                                0).count()):
                        #Тип элемента GUI (если это тип удалить или редактировать (кнопки), то обновляем их ID-ки после удаления перевода)
                        rowItemWidgetType = self.vocabularyLayout.itemAt(
                            horizontalRow).itemAt(0).itemAt(
                                itemInRow).widget().property('type')
                        if (rowItemWidgetType == self.editType
                                or rowItemWidgetType == self.deleteType):
                            self.vocabularyLayout.itemAt(horizontalRow).itemAt(
                                0).itemAt(itemInRow).widget().setProperty(
                                    'id', i)
                i += 1
            del self.initDataVocabulary[keyAttr]
            with open(self.vocabularyFileName + '.json', 'w') as f:
                json.dump(self.initDataVocabulary, f)
            self.indexVocabulary()

    def editClick(self):
        self.dialog = QDialog(self)
        self.dialog.ui = uic.loadUi('editTranslateDialog.ui', self.dialog)
        translateKey = self.sender().property('key')
        self.renderDialog(self.initDataVocabulary[translateKey],
                          key=translateKey,
                          type='edit')

    def clickBtnAddTranslate(self, values=None):
        #инициализация диалогового окна и установка дизайна (пустой layout)
        self.dialog = QDialog(self)
        self.dialog.ui = uic.loadUi('addTranslateDialog.ui', self.dialog)
        self.renderDialog()

    def renderDialog(self, values=None, key=None, type='save'):
        layout = QVBoxLayout()
        # Ключ перевода (добавляем на layout метку и инпут)
        keyRow = QHBoxLayout()
        keyRow.addWidget(QLabel('Ключ', objectName='textLabel'))
        if key is not None:
            keyInput = QtWidgets.QLineEdit(key, objectName='inputField')
        else:
            keyInput = QtWidgets.QLineEdit(objectName='inputField')
        keyInput.setProperty('name', 'key')
        keyRow.addWidget(keyInput)
        layout.addLayout(keyRow)
        layout.addStretch(1)
        # Локализованные значения (сами переводы)
        for lang in self.langs:
            langRowHorizontal = QHBoxLayout()
            lng = QLabel(lang, objectName='textLabel')
            if values is not None:
                lngInput = QtWidgets.QLineEdit(values[lang],
                                               objectName='inputField')
            else:
                lngInput = QtWidgets.QLineEdit(objectName='inputField')
            lngInput.setProperty('name', lang)
            langRowHorizontal.addWidget(lng)
            langRowHorizontal.addWidget(lngInput)
            layout.addLayout(langRowHorizontal)
            layout.addStretch(1)
        layout.addStretch(1)

        # Кнопки взаимодействия с диалоговым окном (сохранить и отмена - закрыть диалог)
        buttonsRow = QHBoxLayout()
        saveButton = QPushButton(
            'Сохранить',
            objectName='saveButton' if type == 'save' else 'editButton')
        cancelButton = QPushButton('Отмена', objectName='cancelButton')
        # Обработчик нажатия  кнопок (отмена и сохранить)
        cancelButton.clicked.connect(self.cancelDialogClick)
        saveButton.clicked.connect(self.saveTranslateClick if type ==
                                   'save' else self.updateTranslateClick)
        buttonsRow.addWidget(cancelButton)
        buttonsRow.addWidget(saveButton)

        # Информационный текст
        infoRow = QHBoxLayout()
        info = QLabel(
            'Внимание! При редактировании ключа будет создана новая запись в словаре!',
            objectName='dangerLabel')
        infoRow.addWidget(info)

        layout.addLayout(infoRow)
        layout.addStretch(1)
        layout.addLayout(buttonsRow)
        # Устанавливаем стили диалогового окна
        self.dialog.setStyleSheet(open("styles/qLineEdit.qss", "r").read())
        self.dialog.setLayout(layout)
        # Показываем диалоговое окно
        self.dialog.show()

    # Обновляем  перевод в файлы (словари)
    def updateTranslateClick(self):
        dialogData = {}
        # Собираем данные с формы (диалоговое окно)
        emptyInputError = False
        for dialogInput in range(self.dialog.layout().count()):
            if (self.dialog.layout().itemAt(dialogInput).__class__.__name__ ==
                    'QHBoxLayout'):
                dialogItem = self.dialog.layout().itemAt(dialogInput)
                if (dialogItem.itemAt(1) is not None
                        and dialogItem.itemAt(1).widget().property('name') !=
                        None):
                    # Ключ
                    name = self.dialog.layout().itemAt(dialogInput).itemAt(
                        1).widget().property('name')
                    # Значение
                    value = self.dialog.layout().itemAt(dialogInput).itemAt(
                        1).widget().text()
                    # Проверяем на наличие пустых полей
                    if (len(value) < 2):
                        emptyInputError = True
                    dialogData[name] = value
        # В случае пустоты хотя бы в одном из полей информируем пользователя
        if (emptyInputError):
            self.showMessage('Ошибка!', 'Не заполнены все поля', 'warning')
        else:
            newItem = {}
            langValueItem = {}
            # Записываем переводы в файлы локализаций
            for lang in self.langs:
                langValueItem[lang] = dialogData[lang]
            self.initDataVocabulary[dialogData['key']] = langValueItem
            self.writeJson(self.vocabularyFileName, self.initDataVocabulary)
            self.showMessage('Обновлено', 'Перевод успешно обновлен!', 'info')
            # Очищаем поля ввода в диалоговом окне
            for dialogInput in range(self.dialog.layout().count()):
                if (self.dialog.layout().itemAt(dialogInput).__class__.__name__
                        == 'QHBoxLayout'):
                    dialogItem = self.dialog.layout().itemAt(dialogInput)
                    if (dialogItem.itemAt(1) is not None
                            and dialogItem.itemAt(1).widget().property('name')
                            != None):
                        self.dialog.layout().itemAt(dialogInput).itemAt(
                            1).widget().setText('')
            horizontal = GUI.setRow(self, self.langs, dialogData,
                                    dialogData['key'], self.vocabularyLayout)
            self.initVocabulary()
            self.indexVocabulary()

    # Сохраняем перевод в файлы (словари)
    def saveTranslateClick(self):
        dialogData = {}
        #Собираем данные с формы (диалоговое окно)
        emptyInputError = False
        for dialogInput in range(self.dialog.layout().count()):
            if (self.dialog.layout().itemAt(dialogInput).__class__.__name__ ==
                    'QHBoxLayout'):
                dialogItem = self.dialog.layout().itemAt(dialogInput)
                if (dialogItem.itemAt(1) is not None
                        and dialogItem.itemAt(1).widget().property('name') !=
                        None):
                    #Ключ
                    name = self.dialog.layout().itemAt(dialogInput).itemAt(
                        1).widget().property('name')
                    #Значение
                    value = self.dialog.layout().itemAt(dialogInput).itemAt(
                        1).widget().text()
                    # Проверяем на наличие пустых полей
                    if (len(value) < 2):
                        emptyInputError = True
                    dialogData[name] = value
        # В случае пустоты хотя бы в одном из полей информируем пользователя
        if (emptyInputError):
            self.showMessage('Ошибка!', 'Не заполнены все поля', 'warning')
        else:
            newItem = {}
            langValueItem = {}
            #Записываем переводы в файлы локализаций
            for lang in self.langs:
                langValueItem[lang] = dialogData[lang]
            if (self.initDataVocabulary is None
                    or len(self.initDataVocabulary) < 1):
                self.initDataVocabulary = {}
                self.initDataVocabulary[dialogData['key']] = langValueItem
                self.initTableHeader()
                self.initVocabulary()
            else:
                self.initDataVocabulary[dialogData['key']] = langValueItem
            self.writeJson(self.vocabularyFileName, self.initDataVocabulary)
            self.showMessage('Сохранено', 'Перевод успешно добавлен!', 'info')
            # Очищаем поля ввода в диалоговом окне
            for dialogInput in range(self.dialog.layout().count()):
                if (self.dialog.layout().itemAt(dialogInput).__class__.__name__
                        == 'QHBoxLayout'):
                    dialogItem = self.dialog.layout().itemAt(dialogInput)
                    if (dialogItem.itemAt(1) is not None
                            and dialogItem.itemAt(1).widget().property('name')
                            != None):
                        self.dialog.layout().itemAt(dialogInput).itemAt(
                            1).widget().setText('')
            horizontal = GUI.setRow(self, self.langs, dialogData,
                                    dialogData['key'], self.vocabularyLayout)
            self.initVocabulary()
            self.indexVocabulary()

    # Закрываем диалоговое окно
    def cancelDialogClick(self):
        self.dialog.close()

    def to_json(self, inputJson):
        try:
            json_object = json.load(inputJson)
        except ValueError as e:
            return None
        return json_object

    def getInputs(self):
        return (self.first.text(), self.second.text())

    # def getFiles(self, dir = ''):
    #     if(len(dir) > 0) :
    #         return [f for f in listdir(dir) if isfile(join(dir, f))]
    #
    # def getDirs(self, dir=''):
    #         return [f for f in listdir(dir) if isdir(join(dir, f))]

    ################------------------------####################
    ########****Запускаем работу скрипта(Laravel)****################
    ################------------------------####################
    def clickBtnRunLaravel(self):
        try:
            Laravel.run(self.settingsLaravelRootDir, self.setting_main_lang)
        except FileNotFoundError as f:
            self.showMessage('Ошибка!', 'Не верно указан путь к файлу!',
                             'critical')

    def __init__(self):
        # Это здесь нужно для доступа к переменным, методам
        # и т.д. в файле html.py
        super().__init__()
        self.setupUi(self)  # Это нужно для инициализации нашего дизайна

        # Информационное окно
        self.msg = QtWidgets.QMessageBox()

        #Инициализация входной и выходной строки
        self.input = ''
        self.output = ''

        #Загрузка настроек из файла
        self.load_settings()

        # Длина строки перевода (отоюражение в словаре)
        self.translateLen = 25

        #Языки
        self.langs = self.setting_langs.split('|')
        self.default_lang = self.setting_main_lang

        #Типы кнопок (удалить, редактировать)
        self.editType = 'edit'
        self.deleteType = 'delete'

        #Загрузка словаря
        self.vocabularyFileName = 'vocabulary'
        self.vocabularyLayout = self.scrollArea
        #Загрузка  данных словаря
        with open(self.vocabularyFileName + '.json', 'r') as inputData:
            self.initDataVocabulary = self.to_json(inputData)
        #Функции инициализации

        if (self.initDataVocabulary is not None
                and len(self.initDataVocabulary) > 0):
            self.indexVocabulary()
            self.initTableHeader()
            self.initVocabulary()

        #Обработчики нажатия кнопок
        self.btn_run.clicked.connect(self.click_btn_run)
        self.btn_save_settings.clicked.connect(self.click_btn_save_settings)
        self.btn_translate_file.clicked.connect(self.click_btn_translate_file)
        self.addTranslate.clicked.connect(self.clickBtnAddTranslate)
        #Laravel
        self.btnLaravelRoot.clicked.connect(self.clickBtnLaravelRoot)
        self.btnRunLaravel.clicked.connect(self.clickBtnRunLaravel)

        #Обработчик события изменение позиции курсора
        #self.main_input.cursorPositionChanged.connect(self.changeInput)

    def load_settings(self):
        # Читаем настройки из файла
        self.settings_path = 'settings.ini'
        if os.path.exists(self.settings_path):
            settings = configparser.ConfigParser()
            settings.read(self.settings_path)
            # GENERAL
            self.setting_langs = settings.get('GENERAL', 'LANGS')
            self.setting_main_lang = settings.get('GENERAL', 'MAIN_LANG')
            self.setting_file_translates = settings.get(
                'MODX', 'FILE_TRANSLATES')
            self.setting_l_placeholder = settings.get('MODX',
                                                      'LEFT_PLACEHOLDER')
            self.setting_r_placeholder = settings.get('MODX',
                                                      'RIGHT_PLACEHOLDER')
            #LARAVEl
            self.settingsLeftLaravelPlaceholder = settings.get(
                'LARAVEL', 'LEFT_LARAVEL_PLACEHOLDER')
            self.settingsRightLaravelPlaceholder = settings.get(
                'LARAVEL', 'RIGHT_LARAVEL_PLACEHOLDER')
            self.settingsLaravelRootDir = settings.get('LARAVEL', 'ROOT_DIR')
            # DB
            self.setting_db_user = settings.get('DB', 'DB_USER')
            self.setting_db_name = settings.get('DB', 'DB_NAME')
            self.setting_db_pass = settings.get('DB', 'DB_PASS')

            # Установка значений настроек из файла на форму
            if len(self.setting_langs) > 0:
                langs_arr = self.setting_langs.split('|')
                if 'ru' in langs_arr:
                    self.ru.setChecked(True)
                if 'en' in langs_arr:
                    self.en.setChecked(True)
                if 'uk' in langs_arr:
                    self.uk.setChecked(True)
                if 'de' in langs_arr:
                    self.de.setChecked(True)
            main_lang = self.main_lang.findText(self.setting_main_lang,
                                                QtCore.Qt.MatchFixedString)
            if main_lang >= 0:
                self.main_lang.setCurrentIndex(main_lang)
            self.file_path.setText(self.setting_file_translates)
            self.l_placeholder.setText(self.setting_l_placeholder)
            self.r_placeholder.setText(self.setting_r_placeholder)
            self.db_user.setText(self.setting_db_user)
            self.db_name.setText(self.setting_db_name)
            self.db_pass.setText(self.setting_db_pass)

            #Laravel
            self.laravelRootDir.setText(self.settingsLaravelRootDir)
            self.leftLaravelPlaceholder.setText(
                self.settingsLeftLaravelPlaceholder)
            self.rightLaravelPlaceholder.setText(
                self.settingsRightLaravelPlaceholder)

    # def changeInput (self):
    #     input = self.main_input
    #     #self.input = self.main_input.toPlainText()
    #     #str_output = self.input.replace('<div>', "[#" + str(exist_id) + "#]")
    #     input.setText("<div></div>")
    #     #print(self.input)

    ################------------------------####################
    #############****Выбор файла переводов****##################
    ################------------------------####################
    def click_btn_translate_file(self):
        fname, _filter = QtWidgets.QFileDialog.getOpenFileName(
            self, 'Выберите файл')
        self.file_path.setText(fname)

    ################------------------------####################
    #######****Выбор корневой директории шаблонов****###########
    ################------------------------####################
    def clickBtnLaravelRoot(self):
        dirName = QtWidgets.QFileDialog.getExistingDirectory(
            self, 'Выберите директорию', '/home')
        self.laravelRootDir.setText(dirName)

    ################------------------------####################
    #############****Обновление настроек****####################
    ################------------------------####################
    def click_btn_save_settings(self):
        # языки для переводов
        langs = []
        if self.ru.isChecked():
            langs.append('ru')
        if self.en.isChecked():
            langs.append('en')
        if self.uk.isChecked():
            langs.append('uk')
        if self.de.isChecked():
            langs.append('de')
        # Основной язык
        m_lang = self.main_lang.currentText()
        #База данных
        db_user = self.db_user.text()
        db_pass = self.db_pass.text()
        db_name = self.db_name.text()

        # Путь к файлу переводов
        file_translates = self.file_path.text()

        #Корневая директория шаблонов Laravel
        laravelRootDir = self.laravelRootDir.text()

        #Плейсхолдеры
        l_placeholder = self.l_placeholder.text()
        r_placeholder = self.r_placeholder.text()
        leftLaravelPlaceholder = self.leftLaravelPlaceholder.text()
        rightLaravelPlaceholder = self.rightLaravelPlaceholder.text()

        #Подтверждение сохранения настроек
        buttonReply = QtWidgets.QMessageBox.question(
            self, 'Изменение настроек', "Сохранить выбранные настройки?",
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if buttonReply == QtWidgets.QMessageBox.Yes:
            settings = configparser.ConfigParser()

            settings['GENERAL'] = {
                'LANGS': '|'.join(langs),
                'MAIN_LANG': m_lang,
            }

            settings['MODX'] = {
                'FILE_TRANSLATES': file_translates,
                'LEFT_PLACEHOLDER': l_placeholder,
                'RIGHT_PLACEHOLDER': r_placeholder,
            }

            settings['LARAVEL'] = {
                'LEFT_LARAVEL_PLACEHOLDER': leftLaravelPlaceholder,
                'RIGHT_LARAVEL_PLACEHOLDER': rightLaravelPlaceholder,
                'ROOT_DIR': laravelRootDir,
            }

            settings['DB'] = {
                'DB_USER': db_user,
                'DB_NAME': db_name,
                'DB_PASS': db_pass,
            }
            with open(self.settings_path, "w") as config_file:
                settings.write(config_file)
            self.load_settings()

    def filter_values(self, x):
        if (re.findall(
                r'^{{.+}}$|^{!!.+!!}$|^@|^{{\s.+}}|^:{{.+}}$|^\+{{.+}}$', x)):
            return 0
        return 1

    ################------------------------####################
    ############****Запускаем работу скрипта****################
    ################------------------------####################
    def click_btn_run(self):
        # Получаем все переводы из файла
        translate_path = Path(self.setting_file_translates)
        try:
            translate_path.owner()
            translate_file_content = check_output([
                'php', '-r', 'include "' + self.setting_file_translates +
                '"; echo json_encode($l);'
            ])
            translate_file_content = json.loads(translate_file_content)

            # Введенный фрагмент
            self.input = self.output = self.main_input.toPlainText()
            soup = BeautifulSoup(self.input, 'html.parser')
            for script in soup(["script", "style"]):
                script.extract()  # rip it out
            text = soup.get_text()
            # break into lines and remove leading and trailing space on each
            lines = (line.strip() for line in text.splitlines())
            # break multi-headlines into a line each
            chunks = [c for c in filter(None, lines)]

            chunks = filter(self.filter_values, chunks)
            for v in chunks:
                print(v)
            sys.exit(0)

            # Массив с переводами которые уже есть в БД (и которые не нужно будет переводить)
            exist_translates = DB.check_translates(self.setting_db_name,
                                                   self.setting_db_user,
                                                   self.setting_db_pass,
                                                   self.setting_main_lang,
                                                   chunks)

            # Подставляем ID существующих переводов, и удаляем эти элементы из списка (chunks)
            if (len(exist_translates) > 0):
                for translate in exist_translates:
                    self.output = self.output.replace(
                        translate[self.setting_main_lang],
                        str(self.setting_l_placeholder) +
                        str(translate['lang_id']) +
                        str(self.setting_r_placeholder))
                    chunks.pop(chunks.index(translate[self.setting_main_lang]))

            # Перебираем оставщиеся строки, требующие перевода
            translator = Translator()
            translator.session.proxies['http'] = '125.26.109.83:8141'
            translator.session.proxies['http'] = '98.221.88.193:64312'
            translator.session.proxies['http'] = '188.244.35.162:10801'
            translator.session.proxies['http'] = '185.162.0.110:10801'

            # языки
            langs = self.setting_langs.split('|')

            # Прогресс бар
            i = 0
            self.progressBar.setMaximum(len(chunks) + 1)
            # Прогресс бар

            for item in chunks:

                # Прогресс бар
                i += 1
                self.progressBar.setValue(i)
                # Прогресс бар

                translate_file_string = []
                translate_dic = {}
                translate_dic[self.setting_main_lang] = item

                # строка для файла переводов
                translate_file_string = []
                for lang in langs:
                    new_translate = translator.translate(
                        item, src=self.setting_main_lang, dest=lang).text
                    translate_dic[lang] = new_translate  # Пауза для гугла
                    sleep(3)

                # для запроса в базу (корректировка языков)
                correct_lang_sql = []
                # значения для записи в базу
                string_sql_values = []
                for item in translate_dic.items():
                    print(item[0] + '--------' + item[1])
                    correct_lang_sql.append(DB.lang_field_connector(item[0]))
                    string_sql_values.append("'" + item[1] + "'")
                    # Строка для записи в файл переводов
                    translate_file_string.append('"' + item[0] + '": "' +
                                                 item[1] + '"')
                langs_sql = ','.join(correct_lang_sql)
                string_sql_values = ','.join(string_sql_values)

                # Запись в БД
                sql = "INSERT INTO modx_a_lang (" + langs_sql + ") VALUES (" + string_sql_values + ");"
                # values = (translate_dic["uk"], translate_dic["ru"], translate_dic["en"]);
                last_id = DB.add_translate(self.setting_db_name,
                                           self.setting_db_user,
                                           self.setting_db_pass, sql)

                # Запись в файл переводов
                translate_file_string = '{' + ','.join(
                    translate_file_string) + '}'
                translate_file_string = json.loads(translate_file_string)

                # Добавление нового перевода в строку json переводов
                translate_file_content[last_id] = translate_file_string
                self.output = self.output.replace(
                    translate_dic[self.setting_main_lang],
                    "[#" + str(last_id) + "#]")

            self.write_to_file(translate_file_content,
                               self.setting_file_translates)
            # subprocess.call(['chmod', '0777', '"' + self.setting_file_translates + '"'])
            self.main_input.setPlainText(self.output)
            # Информационное сообщение о завершении работы
            self.showMessage(
                "Перевод завершен!",
                "Перевод фрагмента html выполнен. Теперь вы можете его скопировать и добавить в свой шаблон!",
                'info')
        except FileNotFoundError as f:
            self.showMessage('Ошибка!', 'Не верно указан путь к файлу!',
                             'critical')

    ################------------------------####################
    ############**********Запись в файл*********################
    ################------------------------####################
    def write_to_file(self,
                      json_string,
                      path="D:\OSPanel\domains\shop.loc\dump.php"):
        f = codecs.open(path, "w+", "utf-8")
        f.write('<?php \n $l=[')
        tr_strings = []
        for l_id, value in json_string.items():
            single_tr = str(l_id) + "=>["
            # Массив переводов одного слова(предложения)
            tr_langs = []
            for lang, v in value.items():
                tr_langs.append("'" + lang + "'=>'" + v + "'")
            # Массив переводов строк
            single_tr += ','.join(tr_langs) + "],"
            f.write(single_tr)
        f.write('];')
        f.close()
        return True

    #########****************************************###########
    #########****Показать сообщение пользователю*****###########
    #########****************************************###########
    def showMessage(self, title, message, icon):
        icons = {
            'info': QtWidgets.QMessageBox.Information,
            'warning': QtWidgets.QMessageBox.Warning,
            'critical': QtWidgets.QMessageBox.Critical,
        }
        self.msg.setIcon(icons[icon])
        self.msg.setWindowTitle(title)
        self.msg.setText(message)
        self.msg.exec_()
コード例 #21
0
class MainWindow(QMainWindow):
    def __init__(self, root):
        super().__init__()
        self.scroll = QScrollArea(
        )  # Scroll Area which contains the widgets, set as the centralWidget
        self.widget = QWidget(
        )  # Widget that contains the collection of Vertical Box
        self.vbox = QVBoxLayout(
        )  # The Vertical Box that contains the Horizontal Boxes of  labels and buttons
        self.root = root
        self.directory_text = DirText(self)
        self.hbox = QHBoxLayout()
        self.back_button = QPushButton()
        self.back_button.clicked.connect(lambda: self.execute_prev_string())
        self.back_button.setStyleSheet("background-color: lightblue;")
        box_layout = QHBoxLayout()
        box_layout.addWidget(self.back_button)
        box_layout.addWidget(self.directory_text)

        self.back_button.setIcon(QIcon("arrow.png"))
        self.vbox.addLayout(box_layout)
        self.setStyleSheet("background-color: white;")
        self.current_dir = "/"
        self.directory_list = ["/"]
        self.initUI(root)

    def initUI(self, root):

        self.widget.setLayout(self.vbox)
        # Scroll Area Properties
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # self.scroll.setHorizontalScrollBarPolicy()
        self.scroll.setWidgetResizable(True)
        self.scroll.setWidget(self.widget)
        self.setCentralWidget(self.scroll)
        self.setGeometry(600, 100, 1000, 900)
        self.setWindowTitle('Scroll Area Demonstration')
        self.show()

        return

    def resetQbox(self):
        for i in reversed(range(self.vbox.count())):
            if i == 0:
                continue
            if isinstance(self.vbox.itemAt(i), QHBoxLayout):
                for j in reversed(range(self.vbox.itemAt(i).count())):
                    self.vbox.itemAt(i).itemAt(j).widget().setParent(None)
                self.vbox.removeItem(self.vbox.itemAt(i))
                continue
            self.vbox.itemAt(i).widget().setParent(None)

    def addToVbox(self, item):
        self.vbox.addLayout(item)
        self.vbox.setAlignment(Qt.AlignTop)

    # def mousePressEvent(self, QMouseEvent):
    #     self.resetQbox()

    def mouseDoubleClickEvent(self, QMouseEvent):
        print("xd doubble baby")

    def check_file_and_set(self, path):
        if path == "":
            self.directory_text.setText(self.current_dir)
        if path[0] == "/" and len(path) == 1:
            self.set_directory_interface(self.root, ["/"])

        string_list = path.split("/")[1:]
        if self.root is not None:
            if path == "/":
                self.set_directory_interface(self.root, ["/"])
                return
            folder = self.check_directory(self.root.file_inside, string_list)
            # ocupo añadir cosas aqui
            if folder == 1 or folder == 2:
                return
            self.set_directory_interface(folder, string_list)

    def check_directory(self, file_list, list_strings):
        file_to_return = None
        for name in list_strings:
            file_to_return = self.get_file_inside(name, file_list)
            if file_to_return == 1:
                pass
            elif file_to_return == 2:
                pass
            else:
                file_list = file_to_return.file_inside
        return file_to_return

    def get_file_inside(self, file_name, file_list):
        for file in file_list:
            if file.file_name == file_name:
                if file.type == "folder":
                    return file
                else:
                    return 1
        return 2

    def set_directory_interface(self, file, string_list):
        self.resetQbox()
        i = 0
        box_layout = QHBoxLayout()

        for file in file.file_inside:

            if i % 5 == 0:
                box_layout = QHBoxLayout()
                box_layout.setAlignment(Qt.AlignLeft)
                self.addToVbox(box_layout)
            i += 1
            file.reset_labels(self)
            box_layout.addWidget(file.label)
            box_layout.addWidget(file.label_data)
        # if i%2==0:
        #     print("Entre")
        #     var =QLabel()
        #     var2 =QLabel()
        #     box_layout.addWidget(var)
        #     box_layout.addWidget(var2)

        string_text = "/"
        for string in string_list:
            string_text += string + "/"
        if string_text == "///":
            self.directory_list.append(self.current_dir)
            self.current_dir = "/"
            self.directory_text.setText("/")
            return

        self.directory_list.append(self.current_dir)
        self.current_dir = string_text[:len(string_text) - 1]
        self.directory_text.setText(string_text)

    def execute_prev_string(self):
        self.check_file_and_set(self.directory_list[len(self.directory_list) -
                                                    1])
        print("Aqui")
        if len(self.directory_list) == 2:
            self.directory_list.pop(len(self.directory_list) - 1)
            return
        if len(self.directory_list) != 1:
            self.directory_list.pop(len(self.directory_list) - 1)
            self.directory_list.pop(len(self.directory_list) - 1)
            return
コード例 #22
0
ファイル: rms.py プロジェクト: Scummer/carrera-rms
class RmsFrame(QFrame):
    def __init__(self, cu):
        super().__init__()
        self.cu = cu
        self.session = RaceSession()
        self.resetRMS()
        self.buildframe()
        self.driverBtn = {}
        self.driverObj = {}
        self.lapcount = {}
        self.totalTime = {}
        self.laptime = {}
        self.bestlaptime = {}
        self.fuelbar = {}
        self.pits = {}
#        QBAcolor = QByteArray()
#        QBAcolor.append('color')
#        self.animation = anim = QPropertyAnimation(self, QBAcolor, self)
#        anim.setDuration(250)
#        anim.setLoopCount(2)
#        anim.setStartValue(QColor(230,230, 0))
#        anim.setEndValue(QColor(0, 0, 0))
#        anim.setKeyValueAt(0.5, QColor(150,100,0))

    def buildframe(self):
        self.vLayout = QVBoxLayout(self)
        self.hBtnLayout = QHBoxLayout()
        self.vLayout.addLayout(self.hBtnLayout)
        # Add driver to grid
        self.addDriverBtn = QPushButton('(A)dd Driver')
        self.addDriverKey = QShortcut(QKeySequence("a"), self)
        self.hBtnLayout.addWidget(self.addDriverBtn)
        self.addDriverBtn.clicked.connect(self.addDriver)
        self.addDriverKey.activated.connect(self.addDriver)
        # Assign Controller
        self.assignCtrlBtn = QPushButton('Assign Controller')
        self.hBtnLayout.addWidget(self.assignCtrlBtn)
        self.assignCtrlBtn.clicked.connect(self.openCtrlDialog)
        # Setup a race
        self.setupRace = QPushButton('Setup a Race')
        self.hBtnLayout.addWidget(self.setupRace)
        self.setupRace.clicked.connect(self.openRaceDlg)
        # Code cars
        self.codeBtn = QPushButton('(C)ode')
        self.codeKey = QShortcut(QKeySequence("c"), self)
        self.hBtnLayout.addWidget(self.codeBtn)
        self.codeBtn.clicked.connect(self.pressCode)
        self.codeKey.activated.connect(self.pressCode)
        # Start pace car
        self.paceBtn = QPushButton('(P)ace')
        self.paceKey = QShortcut(QKeySequence("p"), self)
        self.hBtnLayout.addWidget(self.paceBtn)
        self.paceBtn.clicked.connect(self.setPace)
        self.paceKey.activated.connect(self.setPace)
        # set Speed
        self.setSpeedBtn = QPushButton('Set (S)peed')
        self.setSpeedKey = QShortcut(QKeySequence("s"), self)
        self.hBtnLayout.addWidget(self.setSpeedBtn)
        self.setSpeedBtn.clicked.connect(self.setSpeed)
        self.setSpeedKey.activated.connect(self.setSpeed)
        # set Brakes
        self.setBrakeBtn = QPushButton('Set (B)rake')
        self.setBrakeKey = QShortcut(QKeySequence("b"), self)
        self.hBtnLayout.addWidget(self.setBrakeBtn)
        self.setBrakeBtn.clicked.connect(self.setBrake)
        self.setBrakeKey.activated.connect(self.setBrake)
        # Set Fuel
        self.setFuelBtn = QPushButton('Set (F)uel')
        self.setFuelKey = QShortcut(QKeySequence("f"), self)
        self.hBtnLayout.addWidget(self.setFuelBtn)
        self.setFuelBtn.clicked.connect(self.setFuel)
        self.setFuelKey.activated.connect(self.setFuel)
        # Reset CU
        self.resetBtn = QPushButton('(R)eset')
        self.resetKey = QShortcut(QKeySequence("r"), self)
        self.hBtnLayout.addWidget(self.resetBtn)
        self.resetBtn.clicked.connect(self.resetRMS)
        self.resetKey.activated.connect(self.resetRMS)
        # Start/Pause Race Enter
        self.startRaceBtn = QPushButton(
            'Start Race or Enter changed Settings (Spacebar)')
        self.startRaceBtn.clicked.connect(self.racestart)
        self.spacekey = QShortcut(QKeySequence("Space"), self)
        self.spacekey.activated.connect(self.racestart)
        self.hStartBtnLayout = QHBoxLayout()
        self.hStartBtnLayout.addStretch(1)
        self.hStartBtnLayout.addWidget(self.startRaceBtn)
        self.hStartBtnLayout.setAlignment(self.startRaceBtn, Qt.AlignHCenter)
        self.hStartBtnLayout.addStretch(1)
        self.pitLaneStatus = QLabel()
        self.hStartBtnLayout.addWidget(QLabel('Pitlane'))
        self.hStartBtnLayout.addWidget(self.pitLaneStatus)
        self.fuelmode = QLabel()
        self.hStartBtnLayout.addWidget(QLabel('Fuel Mode'))
        self.hStartBtnLayout.addWidget(self.fuelmode)
        self.lapCounter = QLabel()
        self.hStartBtnLayout.addWidget(QLabel('Lap Counter'))
        self.hStartBtnLayout.addWidget(self.lapCounter)
        self.vLayout.addLayout(self.hStartBtnLayout)
        self.vLayout.setAlignment(self.hStartBtnLayout, Qt.AlignTop)
        #        self.sepline = QFrame()
        #        self.sepline.setFrameShape(QFrame.HLine)
        #        self.sepline.setFrameShadow(QFrame.Sunken)
        #        self.vLayout.addWidget(self.sepline)
        #        self.vLayout.setAlignment(self.sepline, Qt.AlignTop)
        # Driver Grid
        self.vLayout.addLayout(self.buildGrid())
        # Session Info
        self.racemode = QLabel('No Race Started')
        self.racemode.setAlignment(Qt.AlignCenter)
        self.racemode.setStyleSheet(
            "QLabel{ border-radius: 10px; background-color: grey; center; color: blue; font: 30pt}"
        )
        self.vLayout.addWidget(self.racemode)
        self.vLayout.setAlignment(self.racemode, Qt.AlignBottom)

    def buildGrid(self):
        self.mainLayout = QGridLayout()
        self.mainLayout.setSpacing(10)
        self.mainLayout.setHorizontalSpacing(10)
        self.headerFont = QFont()
        self.headerFont.setPointSize(14)
        self.headerFont.setBold(True)
        self.labelArr = [
            'Pos', 'Driver', 'Total', 'Laps', 'Laptime', 'Best Lap', 'Fuel',
            'Pits'
        ]
        for index, label in enumerate(self.labelArr):
            self.headerLabel = QLabel(label)
            self.headerLabel.setFont(self.headerFont)
            self.mainLayout.addWidget(self.headerLabel, 0, index,
                                      Qt.AlignHCenter)
        self.mainLayout.setColumnStretch(1, 1)
        self.mainLayout.setColumnStretch(2, 1)
        self.mainLayout.setColumnStretch(3, 2)
        self.mainLayout.setColumnStretch(4, 3)
        self.mainLayout.setColumnStretch(5, 3)
        self.mainLayout.setColumnStretch(6, 2)
        self.mainLayout.setColumnStretch(7, 1)
        return self.mainLayout

    def openCtrlDialog(self):
        self.ctrlDialog = CtrlDialog(self.driverArr)
        if self.ctrlDialog.exec_():
            self.driverArr = self.ctrlDialog.newDriverArr

    def openRaceDlg(self):
        self.setupRaceDlg = RaceModeDialog()
        self.session.session = None
        self.session.type = None
        if self.setupRaceDlg.exec_():
            for driver in self.driverArr:
                driver.bestLapTime = None
                driver.time = None
                driver.lapcount = 0
                driver.pitcount = 0
            self.session.setRace(self.setupRaceDlg.getRaceModeInfo())
            self.racemode.setText(self.session.session + ' ' +
                                  str(self.session.amount) + ' ' +
                                  self.session.type)
            self.clearCU()
            self.cu.start()
        else:
            self.setupRaceDlg.close()

    def getColor(self):
        if self.mainLayout.itemAtPosition(1, 1):
            return self.mainLayout.itemAtPosition(1,
                                                  1).widget().palette().text()
        else:
            return None

    def setColor(self, color):
        PBwidget = self.mainLayout.itemAtPosition(1, 1).widget()
        palette = PBwidget.palette()
        palette.setColor(PBwidget.foregroundRole(), color)
        PBwidget.setFlat(True)
        PBwidget.setAutoFillBackground(True)
        PBwidget.setPalette(palette)

    color = pyqtProperty(QColor, getColor, setColor)

    def addDriver(self):
        driverRow = self.mainLayout.rowCount()
        if driverRow > 8:
            return
        driver = self.driverArr[driverRow - 1]
        self.posFont = QFont()
        self.posFont.setPointSize(35)
        self.posFont.setBold(True)
        self.driverPos = QLabel(str(driverRow))
        self.driverPos.setStyleSheet(
            "QLabel{ border-radius: 10px; border-color: black; border: 5px solid black; background-color: white}"
        )
        self.driverPos.setSizePolicy(QSizePolicy.Maximum,
                                     QSizePolicy.Expanding)
        self.driverPos.setFont(self.posFont)
        self.mainLayout.addWidget(self.driverPos, driverRow, 0)
        self.driverBtn[driverRow] = driver.getNameBtn()
        self.driverBtn[driverRow].setSizePolicy(QSizePolicy.Preferred,
                                                QSizePolicy.Expanding)
        self.mainLayout.addWidget(self.driverBtn[driverRow], driverRow, 1)
        self.driverObj[driverRow] = driver
        self.driverBtn[driverRow].clicked.connect(lambda: self.changeDriver(
            self.driverBtn[driverRow], self.driverObj[driverRow]))
        self.lapcount[driverRow] = driver.getLapCountLCD()
        self.lapcount[driverRow].setSizePolicy(QSizePolicy.Preferred,
                                               QSizePolicy.Expanding)
        self.mainLayout.addWidget(self.lapcount[driverRow], driverRow, 3)
        self.totalFont = QFont()
        self.totalFont.setPointSize(25)
        self.totalFont.setBold(True)
        self.totalTime[driverRow] = QLabel('00:00')
        self.totalTime[driverRow].setStyleSheet(
            "QLabel{ border-radius: 10px; border-color: black; border: 5px solid black; background-color: white}"
        )
        self.totalTime[driverRow].setSizePolicy(QSizePolicy.Preferred,
                                                QSizePolicy.Expanding)
        self.totalTime[driverRow].setFont(self.totalFont)
        self.mainLayout.addWidget(self.totalTime[driverRow], driverRow, 2)
        self.laptime[driverRow] = driver.getLapLCD()
        self.laptime[driverRow].setSizePolicy(QSizePolicy.Preferred,
                                              QSizePolicy.Expanding)
        self.mainLayout.addWidget(self.laptime[driverRow], driverRow, 4)
        self.bestlaptime[driverRow] = driver.getBestLapLCD()
        self.bestlaptime[driverRow].setSizePolicy(QSizePolicy.Preferred,
                                                  QSizePolicy.Expanding)
        self.mainLayout.addWidget(self.bestlaptime[driverRow], driverRow, 5)
        self.fuelbar[driverRow] = driver.getFuelBar()
        self.fuelbar[driverRow].setSizePolicy(QSizePolicy.Minimum,
                                              QSizePolicy.Preferred)
        self.mainLayout.addWidget(self.fuelbar[driverRow], driverRow, 6)
        self.pits[driverRow] = driver.getPits()
        self.pits[driverRow].setSizePolicy(QSizePolicy.Preferred,
                                           QSizePolicy.Preferred)
        self.mainLayout.addWidget(self.pits[driverRow], driverRow, 7)

    def racestart(self):
        self.cu.start()
#        self.mainLayout.itemAtPosition(1, 5).widget().setPits('Pit')
#        self.mainLayout.itemAtPosition(1, 5).widget().setPits('Track')

    def resetRMS(self):
        if hasattr(self, 'driverArr'):
            for driverObj in self.driverArr:
                driverObj.deleteLater()
        self.start = None
        self.driverArr = [RmsDriver(num) for num in range(1, 9)]

        self.clearCU()

        if hasattr(self, 'mainLayout'):
            while True:
                widgetToRemove = self.mainLayout.takeAt(0)
                if widgetToRemove == None:
                    break
                widgetToRemove.widget().deleteLater()
            racemode = self.vLayout.takeAt(3)
            mainItem = self.vLayout.takeAt(2)
            self.vLayout.removeItem(racemode)
            self.vLayout.removeItem(mainItem)
            mainItem.deleteLater()
            self.vLayout.addLayout(self.buildGrid())
            self.vLayout.addWidget(self.racemode)

    def clearCU(self):
        # discard remaining timer messages
        status = self.cu.request()
        while not isinstance(status, ControlUnit.Status):
            status = self.cu.request()
        self.status = status
        # reset cu timer
        self.cu.reset()

    def pressCode(self):
        print('press Code')
        self.cu.request(b'T8')

    def setFuel(self):
        print('set fuel')
        self.cu.request(b'T7')

    def setPace(self):
        print('pace car')
        self.cu.request(b'T1')

    def setSpeed(self):
        print('set speed')
        self.cu.request(b'T5')

    def setBrake(self):
        print('set brake')
        self.cu.request(b'T6')

    def changeDriver(self, driverButton, driverObj):
        self.driverChangeText = QInputDialog.getText(
            self, 'Change driver name', 'Driver Name', 0,
            driverButton.text().split('\n')[0])
        if self.driverChangeText[1] == True:
            driverButton.setText(self.driverChangeText[0] + '\n' + 'Ctrl: ' +
                                 str(driverObj.CtrlNum))
            driverObj.name = self.driverChangeText[0]

    def updateDisplay(self, binMode):
        if binMode != None:
            if binMode[2] == '1':
                self.fuelmode.setText('Real')
            elif binMode[3] == '1':
                self.fuelmode.setText('On')
            elif binMode[3] == '0':
                self.fuelmode.setText('Off')
            if binMode[1] == '1':
                self.pitLaneStatus.setText('Exists')
            else:
                self.pitLaneStatus.setText('Missing')
            if binMode[0] == '1':
                self.lapCounter.setText('Exists')
            else:
                self.lapCounter.setText('Missing')

        driversInPlay = [driver for driver in self.driverArr if driver.time]
        if len(driversInPlay) + 1 > self.mainLayout.rowCount():
            self.addDriver()
        for pos, driver in enumerate(sorted(driversInPlay, key=posgetter),
                                     start=1):
            if pos == 1:
                if hasattr(self, 'leader') and self.leader != driver:
                    print('pos change')


#                self.animation.start()
                self.leader = driver
                t = formattime(driver.time - self.start, True)
            elif driver.lapcount == self.leader.lapcount:
                t = '+%ss' % formattime(driver.time - self.leader.time)
            else:
                gap = self.leader.lapcount - driver.lapcount
                t = '+%d Lap%s' % (gap, 's' if gap != 1 else '')
            self.driverBtn[pos].setText(driver.name + '\n' + 'Ctrl: ' +
                                        str(driver.CtrlNum))
            self.totalTime[pos].setText(t)
            self.lapcount[pos].display(driver.lapcount)
            self.laptime[pos].display(formattime(driver.lapTime))
            self.bestlaptime[pos].display(formattime(driver.bestLapTime))
            self.fuelbar[pos].setValue(driver.fuellevel)
            if driver.fuellevel > 0:
                self.fuelbar[pos].setStyleSheet(
                    "QProgressBar{ color: white; background-color: black; border: 5px solid black; border-radius: 10px; text-align: center}\
                                                 QProgressBar::chunk { background: qlineargradient(x1: 1, y1: 0.5, x2: 0, y2: 0.5, stop: 0 #00AA00, stop: "
                    + str(0.92 - (1 / (driver.fuellevel))) +
                    " #22FF22, stop: " + str(0.921 - (1 /
                                                      (driver.fuellevel))) +
                    " #22FF22, stop: " + str(1.001 - (1 /
                                                      (driver.fuellevel))) +
                    " red, stop: 1 #550000); }")
            self.pits[pos].display(driver.pitcount)
        if hasattr(self, 'leader') and self.session.session != None:
            if self.session.type != None:
                self.racemode.setText(self.session.session + ' ' +
                                      str(self.session.amount) + ' ' +
                                      self.session.type)
            if self.session.type == 'Laps':
                if self.leader.lapcount > self.session.amount:
                    self.racestart()
                    self.session.saveSessionData(driversInPlay)
                    self.clearCU()
                    self.session.sessionOver()
            elif self.session.type == 'Timed':
                if self.leader.time - self.start > self.session.amount * 60000:
                    self.racestart()
                    self.session.saveSessionData(driversInPlay)
                    self.clearCU()
                    self.session.sessionOver()
            elif self.session.type == None:
                self.session.session = None
                self.showLeaderboard()

    def showLeaderboard(self):
        self.leaderBoard = LBDialog(self.session.leaderboard)
        self.leaderBoard.show()
コード例 #23
0
class WidgetRegisterEntryList(QWidget):
    def __init__(self, master, cbRead, cbWrite):
        super().__init__(master)
        # Callbacks
        self.cb_read = cbRead
        self.cb_write = cbWrite

        # Layout
        self.grid = QVBoxLayout()
        self.grid.setSpacing(3)
        self.setLayout(self.grid)

        # Members
        self.entries = []
        self.addresses = []
        self.sizes = []
        self.eeprom_size = 0

    def init(self, register_map):
        self.entries = []
        self.addresses = []
        self.sizes = []
        self.eeprom_size = len(register_map[1])
        for i in reversed(range(self.grid.count())):
            item = self.grid.itemAt(i)
            w = item.widget()
            if w is not None:
                w.deleteLater()
            else:
                self.grid.removeItem(item)
        if len(register_map[1]) > 0:
            label_eeprom = QLabel("EEPROM Area", self)
            label_eeprom.setAlignment(Qt.AlignCenter)
            label_eeprom.setStyleSheet("QLabel { font: bold; }")
            self.grid.addWidget(label_eeprom)
            for e in register_map[1]:
                self._add_reg_entry(e)
        if len(register_map[2]) > 0:
            label_ram = QLabel("RAM Area", self)
            label_ram.setAlignment(Qt.AlignCenter)
            label_ram.setStyleSheet("QLabel { font: bold; }")
            self.grid.addWidget(label_ram)
            for e in register_map[2]:
                self._add_reg_entry(e)
        self.grid.addStretch(1)

    def read_all(self):
        for entry in self.entries:
            entry.read()

    def export_eeprom(self):
        output = []
        for i in range(self.eeprom_size):
            output.append(
                (self.addresses[i],
                 self.sizes[i],
                 self.entries[i].get_gui_value()))
        return output

    def import_eeprom(self, value_list):
        i = 0
        for entry in value_list:
            if len(entry) != 3:
                raise IndexError
            if entry[0] != self.addresses[i]:
                raise ValueError
            if entry[1] != self.sizes[i]:
                raise ValueError
            self.entries[i].set_gui_value(entry[2])
            i += 1

    #  Wrapper to make the use of 'partial' clearer
    def _read(self, address, size):
        return self.cb_read(address, size)

    #  Wrapper to make the use of 'partial' clearer
    def _write(self, address, value, size):
        return self.cb_write(address, size, value)

    def _add_reg_entry(self, reg_entry):
        r_cb = partial(self._read, size=reg_entry[1])
        if reg_entry[3]:
            w_cb = partial(self._write, size=reg_entry[1])
        else:
            w_cb = None
        w = WidgetRegisterEntry(self, reg_entry[0], reg_entry[4], reg_entry[5],
                                reg_entry[2], r_cb, reg_entry[6], w_cb)
        self.entries.append(w)
        self.addresses.append(reg_entry[0])
        self.sizes.append(reg_entry[1])
        self.grid.addWidget(w)
コード例 #24
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1000, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        self.menu_File = QtWidgets.QMenu(self.menubar)
        self.menu_File.setObjectName("menu_File")
        
        MainWindow.setMenuBar(self.menubar)

        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)        
        
        self.action_Exit = QtWidgets.QAction(MainWindow)
        self.action_Exit.setObjectName("action_Exit")
        self.action_Exit.setStatusTip('Exit')
        self.actionOpenFile = QtWidgets.QAction(MainWindow)
        self.actionOpenFile.setObjectName("actionOpenFile")
        self.actionOpenFile.setStatusTip('Open new File')
        self.actionOpenDir = QtWidgets.QAction(MainWindow)
        self.actionOpenDir.setObjectName("actionOpenDir")
        self.actionOpenDir.setStatusTip('Open Directory')
        self.menu_File.addAction(self.actionOpenFile)
        self.menu_File.addAction(self.actionOpenDir)
        self.menu_File.addSeparator()
        self.menu_File.addAction(self.action_Exit)
        self.menubar.addAction(self.menu_File.menuAction())


        self.contentsWidget = QListWidget()
        self.contentsWidget.setViewMode(QListView.ViewMode.IconMode)
        self.contentsWidget.setIconSize(QSize(140,140))					# add icon 2/6
        self.contentsWidget.setMovement(QListView.Movement.Static)		# add icon
        # self.contentsWidget.insertItem(0, 'Linked/Unlinked Bags')		# add icon
        # self.contentsWidget.insertItem(1, 'Simulation Tools')			# add icon
        self.contentsWidget.setMinimumWidth(160)
        self.contentsWidget.setMaximumWidth(160)
        self.contentsWidget.setSpacing(6)								# add icon
        # self.contentsWidget.setMaximumWidth(480)

        self.createIcons()				# add icon

        self.stack1 = QWidget()
        self.stack2 = QWidget()

        self.stack1UI()
        self.stack2UI()

        self.st = QStackedWidget(self.centralwidget)
        self.st.addWidget(self.stack1)
        self.st.addWidget(self.stack2)
        self.st.setMinimumWidth(640)
        self.st.setMinimumHeight(480)

        # print(self.size().width())  # tried to get mainwindow size

        hbox = QHBoxLayout(self.centralwidget)
        hbox.addWidget(self.contentsWidget)
        hbox.addWidget(self.st)
        # hbox.setStretch(1, 100)					# need to check if this line matters 2/12 10:35

        self.centralwidget.setLayout(hbox)
        # self.statusbar = QMainWindow.statusBar(MainWindow)


        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        
        self.contentsWidget.currentRowChanged.connect(self.display)
        self.actionOpenFile.triggered.connect(self.openFile)
        self.actionOpenDir.triggered.connect(self.openDir)
        self.action_Exit.triggered.connect(self.exit)

        # self.createBar()


    def createIcons(self):			# add icon
    	histIcon = QListWidgetItem(self.contentsWidget)
    	histIcon.setIcon(QIcon("icon/hist-icon.jpg"))
    	histIcon.setText("Bin Tracking")
    	histIcon.setTextAlignment(Qt.AlignHCenter)
    	histIcon.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)

    	simuIcon = QListWidgetItem(self.contentsWidget)
    	simuIcon.setIcon(QIcon("icon/simul-icon.png"))
    	simuIcon.setText("Simulation")
    	simuIcon.setTextAlignment(Qt.AlignHCenter)
    	simuIcon.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)


    def createBar(self):
        print("in create bar")
        min_num, max_num = 0, 100
        max_count = 0
        linked_bag_list = []
        try:
            df = self.linked['Beam Diff'].dropna()
            linked_bag_list = df.values.tolist()
            min_num = int(min(linked_bag_list))
            if min_num > 0:                 # check if greater than 0, set to 0
                min_num = 0
            max_num = int(max(linked_bag_list))

        except AttributeError:
            self.statusbar.showMessage('Data not ready')


        count = linked_bag_list
        count = [0] * (max_num + 1)        # choose the largest num as length of count
        
        for num in linked_bag_list:
            count[int(num)] += 1            # update every number's count

        max_count = max(count)

        setBar = QBarSet('Beam Difference Occurrence')
        setBar.append(count)
        brush = QBrush(QColor(0x57B1FD))
        pen = QPen(QColor(0x57B1FD))
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Linked Bins Histogram')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setTitleText("Attenuation Window")
        axisX.setRange(min_num, max_num+20)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setTitleText("Frequency")
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView


    def createUnlinkedBar(self):
        max_count = 0
        unlinked_bag_list = []
        try:
            df = self.unlinked['Beam Diff'].dropna()
            unlinked_bag_list = df.values.tolist()
        except AttributeError:
            self.statusbar.showMessage('Data not ready')

        count = [0] * 4
        for num in unlinked_bag_list:
            if -1000 <= num and num <= -51:
                count[0] += 1
            elif -50 <= num and num <= -1:
                count[1] += 1
            elif 151 <= num and num <= 200:
                count[2] += 1
            elif 201 <= num:
                count[3] += 1

        # print(count)
        max_count = max(count)

        setBar = QBarSet('Beam Difference Occurrence')
        setBar.append(count)

        series = QBarSeries()
        series.append(setBar)
        
        brush = QBrush(QColor(0xfdb157))
        pen = QPen(QColor(0xfdb157))
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Unlinked Bins Summary')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        labels = ['Not useful(-50 to -1000)', 'Pushed by operator(-1 to -50)', 'Slipping on belt(151 to 200)', 'Not useful 201+']
        axisX = QBarCategoryAxis()
        axisX.append(labels)
        # chart.setAxisX(axisX, series)
        chart.addAxis(axisX, Qt.AlignBottom)
        # chart.ChartAreas[0].AxisX.LabelAutoFitStyle = LabelAutoFitStyle.WrodWrap
        series.attachAxis(axisX)

        axisY = QValueAxis()
        axisY.setRange(0, max_count+1)
        # chart.setAxisY(axisY, series)
        chart.addAxis(axisY, Qt.AlignLeft)
        series.attachAxis(axisY)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView



    def createSummaryBar(self):
        # self.dp.dfinal
        series = QPieSeries()
        labelfont = QFont()
        labelfont.setPixelSize(11)
        linked_bag, unlinked_bag = 0, 0
        try:
            linked_bag = len(self.linked.index)
            unlinked_bag = len(self.unlinked.index)

            # slices.setPen(QPen(Qt.darkGreen, 2))
            # slices.setBrush(QBrush(QColor(0xfdb157)))            
        except AttributeError:
            self.statusbar.showMessage('Data not ready')

        series.append("Linked", linked_bag)
        series.append("Unlinked", unlinked_bag)
        slices = series.slices()[0]
        
        slices.setBrush(QBrush(QColor(0x57B1FD)))
        slices.setLabelVisible()
        slices.setLabel(("{0} {1:.2f}%").format("Linked", 100*slices.percentage()))
        slices.setLabelFont(labelfont)

        slices1 = series.slices()[1]
        slices1.setExploded()
        slices1.setLabelVisible()
        slices1.setPen(QPen(QColor(0x57B1FD), 2))
        slices1.setBrush(QBrush(QColor(0xfdb157)))
        # slices1.setLabelPosition(QPieSlice.LabelOutside)
        slices1.setLabel(("{0} {1:.2f}%").format("Unlinked", 100*slices1.percentage()))
        slices1.setLabelFont(labelfont)        
        
        # slices.setLabel(("%1%").format(100*slices.percentage(), 0, 'f', 1))
        # slices.setLabelPosition(QPieSlice.LabelInsideHorizontal)         

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTitle("Total")
        chart.legend().hide()

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        return chartView


    def getCertainRangeList(self, total_time_lst):
        self.ready_to_plot_lst = []
        self.range0To2 = []
        self.range2To3 = []
        self.range3To6 = []
        self.range6To9 = []
        self.range9To20 = []
        for item in total_time_lst:
          if 0 < item and item <= 2:
            # print("in 0-3: ", item)
            self.ready_to_plot_lst.append(int(item))
            self.range0To2.append(item)
          elif 2 < item and item <= 3:
            self.ready_to_plot_lst.append(int(item))
            self.range2To3.append(item)
          elif 3 < item and item <= 6:
            # print("in 3-6: ", item)
            self.ready_to_plot_lst.append(int(item))
            self.range3To6.append(item)
          elif 6 < item and item <= 9:
            # print("in 6-9: ", item)       
            self.range6To9.append(item)
            self.ready_to_plot_lst.append(int(item))
          elif 9 < item and item <= 20:
            self.range9To20.append(item)

    def onClicked(self, b):						# try to add histogram radio button 2/11 12:02
        # self.removeWidgets()
        # self.layout.addWidget(self.createBar())
        if b.text() == "Histogram":
            print("histogram checkd!")
        elif b.text() == "RangeHist":
            print("range histogram")
        elif b.text() == "Pie Chart":
            print("pie chart")

    def stack1UI(self):
        self.flag = False
        self.layout = QVBoxLayout()
        combo = QComboBox(self.stack1)
        combo.addItem("Linked Bags")
        combo.addItem("Unlinked Bags")
        combo.addItem("Summary")

        # self.image = QtWidgets.QLabel(self.stack1)				# try to do stackwidget here 2/10 10:52
        # self.image.setObjectName("imageLabel")						# try to do stackwidget here 2/10 10:52
        # self.chartLayout = QHBoxLayout()                            # add chartLayout 2/13 9:16

        self.layout.addWidget(combo)
        # self.layout.addWidget(self.image)								# add stackwidget 2/10 10:52
        

        # self.chartLayout.addWidget(self.test)
        
        
        
        self.layout.setAlignment(QtCore.Qt.AlignTop)
        # self.layout.addLayout(self.chartLayout)                     # add chartLayout 2/13 9:16

        self.stack1.setLayout(self.layout)

        combo.activated[str].connect(self.onActivated)


    def stack2UI(self):
        self.vlayout = QVBoxLayout()
        hlayout = QHBoxLayout()

        combo1 = QComboBox(self.stack2)
        combo1.addItem("Distribution")
        combo1.addItem("Occurrence")
        combo1.addItem("Summary")

        label = QLabel()
        label.setText("Delay: ")
        self.text = QLineEdit()
        button = QPushButton("Go")

        hlayout.addWidget(combo1)        
        hlayout.addWidget(label)
        hlayout.addWidget(self.text)
        hlayout.addWidget(button)

        self.slayout = QHBoxLayout()

        self.labelDelay = QtWidgets.QLabel(self.stack2)
        self.labelafterDelay = QtWidgets.QLabel(self.stack2)		# try to add a paralel widget (before / after)
        self.labelDelay.setObjectName("result")

        self.labelafterDelay.setObjectName("delayResult")			# try to add a paralel widget (before / after)
        # self.labelDelay.setText("before")
        # self.labelafterDelay.setText("after")						# try to add a paralel widget (before / after)

        self.slayout.addWidget(self.labelDelay)
        self.slayout.addWidget(self.labelafterDelay)

        self.vlayout.addLayout(hlayout)

        self.vlayout.addLayout(self.slayout)
        self.stack2.setLayout(self.vlayout)

        button.clicked.connect(self.simulate)
        combo1.activated[str].connect(self.onActivated1)

    def afterDelayPieChart(self):
        series = QPieSeries()
        labelfont = QFont()
        labelfont.setPixelSize(11)
        total_running_after_delay, total_stopped_after_delay = 0, 0
        try:
        	total_running_after_delay = sum(self.tm.total_running_after_delay)
        	total_stopped_after_delay = sum(self.tm.total_stopped_after_delay)

            # slices.setPen(QPen(Qt.darkGreen, 2))
            # slices.setBrush(QBrush(QColor(0xfdb157)))            
        except AttributeError:
            self.statusbar.showMessage('Data not ready')

        series.append("Run", total_running_after_delay)
        series.append("Stop", total_stopped_after_delay)
        # slices = QPieSlice()
        slices = series.slices()[0]   					# Run time slice
        slices.setBrush(QBrush(QColor(0x57B1FD)))		# Blue
        slices.setLabelVisible()						# Set label visible
        slices.setLabel(("{0} {1:.2f}%").format("Run time", 100*slices.percentage()))	# Set percentage
        slices.setLabelFont(labelfont)        			# Set label font

        slices1 = series.slices()[1]					# Stop time slice
        slices1.setExploded()							# Set stop slice exploded
        slices1.setLabelVisible()						# Set label visible
        slices1.setPen(QPen(QColor(0x57B1FD), 2))		# Blue
        slices1.setBrush(QBrush(QColor(0xA6E22E)))		# Orange
        # slices1.setLabelPosition(QPieSlice.LabelOutside)	# Set label outside
        slices1.setLabel(("{0} {1:.2f}%").format("Stop time", 100*slices1.percentage()))	# Set percentage
        slices1.setLabelFont(labelfont)        			# Set label font

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTitle("Total Time (after)")
        chart.legend().hide()

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        return chartView

    def afterDelay(self):
        # print("in after delay bar")
        min_num, max_num = 0, 100
        max_count = 0
        total_stopped_after_delay = []
        count = [0] * (int(max_num) + 1)        # choose the largest num as length of count
        try:
            total_stopped_after_delay = self.tm.total_stopped_after_delay
            max_num = max(total_stopped_after_delay)
            count = [0] * (int(max_num) + 1)        # choose the largest num as length of count
                 
            for num in total_stopped_after_delay:
                count[int(num)] += 1            # update every number's count

            max_count = max(count)

        except (AttributeError, ValueError):
            self.statusbar.showMessage('Data not ready')

        setBar = QBarSet('Stop Time Occurrence')
        setBar.append(count)
        brush = QBrush(QColor(0xA6E22E))		# Green
        pen = QPen(QColor(0xA6E22E))			# Green
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Stop time Occurrence (after)')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setRange(min_num, max_num+20)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView   

    def afterDelayDistribution(self):
        min_num, max_num = 0, 100
        max_count = 0
        total_stopped_after_delay = []
        count = [0]
        try:
            total_stopped_after_delay = self.tm.total_stopped_after_delay
            max_num = len(total_stopped_after_delay)							# change max() to len(), now it's correct
            count = total_stopped_after_delay
            max_count = max(count)
        except (AttributeError, ValueError):
            self.statusbar.showMessage('Data not ready')

        setBar = QBarSet('stop time')
        setBar.append(count)
        brush = QBrush(QColor(0xA6E22E))		# Green
        pen = QPen(QColor(0xA6E22E))			# Green
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Stop time Distribution (after)')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setRange(min_num, max_num)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView   

    def beforeDelayPieChart(self):
        series = QPieSeries()
        labelfont = QFont()
        labelfont.setPixelSize(11)
        total_running_time, total_stopped_time = 0, 0
        try:
        	total_running_time = sum(self.tm.total_running_time)
        	total_stopped_time = sum(self.tm.total_stopped_time)

            # slices.setPen(QPen(Qt.darkGreen, 2))
            # slices.setBrush(QBrush(QColor(0xfdb157)))            
        except AttributeError:
            self.statusbar.showMessage('Data not ready')

        series.append("Run", total_running_time)
        series.append("Stop", total_stopped_time)

        slices = series.slices()[0]
        slices.setBrush(QBrush(QColor(0x57B1FD)))
        slices.setLabelVisible()
        slices.setLabel(("{0} {1:.2f}%").format("Run Time", 100*slices.percentage()))
        slices.setLabelFont(labelfont)

        slices1 = series.slices()[1]
        slices1.setExploded()
        slices1.setLabelVisible()
        slices1.setPen(QPen(QColor(0x57B1FD), 2))
        slices1.setBrush(QBrush(QColor(0xfdb157)))
        slices1.setLabel(("{0} {1:.2f}%").format("Stop Time", 100*slices1.percentage()))
        slices1.setLabelFont(labelfont)       

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTitle("Total Time (before)")
        chart.legend().hide()

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        return chartView

    def beforeDelay(self):
        # print("in before delay bar")
        min_num, max_num = 0, 100
        max_count = 0
        total_stopped_time = []
        count = [0] * (int(max_num) + 1)        # choose the largest num as length of count
        try:
            total_stopped_time = self.tm.total_stopped_time
            max_num = max(total_stopped_time)
            count = [0] * (int(max_num) + 1)        # choose the largest num as length of count
            
            for num in total_stopped_time:
                count[int(num)] += 1            # update every number's count

            max_count = max(count)        
        except (AttributeError, ValueError):
            self.statusbar.showMessage('Data not ready')

        setBar = QBarSet('Stop Time Occurrence')
        setBar.append(count)
        brush = QBrush(QColor(0x57B1FD))
        pen = QPen(QColor(0x57B1FD))
        pen.setWidth(2)
        setBar.setPen(pen)  
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Stop time Occurrence (before)')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setRange(min_num, max_num+20)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView

    def beforeDelayDistribution(self):
        min_num, max_num = 0, 100
        max_count = 0
        total_stopped_time = []
        count = [0]
        try:
            total_stopped_time = self.tm.total_stopped_time
            max_num = len(total_stopped_time)							# change from max() to len() 2/12 11:11
            count = total_stopped_time
            max_count = max(count)
        except (AttributeError, ValueError):            
            self.statusbar.showMessage('Data not ready')
        
        setBar = QBarSet('stop time')
        setBar.append(count)
        brush = QBrush(QColor(0x57B1FD))
        pen = QPen(QColor(0x57B1FD))
        pen.setWidth(2)
        setBar.setPen(pen)
        setBar.setBrush(brush)

        series = QBarSeries()
        series.append(setBar)

        chart = QChart()
        font = QFont()
        font.setPixelSize(18)
        chart.setTitleFont(font)

        chart.setTitle('Stop time Distribution (before)')
        chart.addSeries(series)
        chart.setAnimationOptions(QChart.SeriesAnimations)

        axisX = QValueAxis()
        axisX.setRange(min_num, max_num)
        chart.setAxisX(axisX, series)

        axisY = QValueAxis()
        axisY.setRange(0, max_count+20)
        chart.setAxisY(axisY, series)

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartView = QChartView(chart)
        chartView.setRenderHint(QPainter.Antialiasing)

        # MainWindow.setCentralWidget(chartView)
        return chartView  

    def display(self, i):
        self.st.setCurrentIndex(i)


    # mainMenu components
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.menu_File.setTitle(_translate("MainWindow", "&File"))
        self.action_Exit.setText(_translate("MainWindow", "&Exit"))
        self.actionOpenFile.setText(_translate("MainWindow", "&Open File/Files"))
        self.actionOpenDir.setText(_translate("MainWindow", "&Open Folder"))

    def removeWidgets(self):
        for i in reversed(range(1,self.layout.count())):                # change 2 to 3 if add another widget(radio)
            self.layout.itemAt(i).widget().setParent(None)

    def removeWidgets1(self):
        for i in reversed(range(1,self.slayout.count())):
            self.slayout.itemAt(i).widget().setParent(None)

    def removeWidgets2(self):
        for i in reversed(range(0,self.chartLayout.count())):
            self.chartLayout.itemAt(i).widget().setParent(None)
        self.layout.removeItem(self.chartLayout)

    def onActivated1(self, text):
    	if text == 'Distribution':
    		self.removeWidgets1()
    		self.slayout.addWidget(self.beforeDelayDistribution(), QtCore.Qt.AlignCenter)
    		self.slayout.addWidget(self.afterDelayDistribution(), QtCore.Qt.AlignCenter)
    	elif text == 'Occurrence':
    		self.removeWidgets1()
    		self.slayout.addWidget(self.beforeDelay(), QtCore.Qt.AlignCenter)
    		self.slayout.addWidget(self.afterDelay(), QtCore.Qt.AlignCenter)
    	elif text == 'Summary':
    		self.removeWidgets1()
    		self.slayout.addWidget(self.beforeDelayPieChart(), QtCore.Qt.AlignCenter)
    		self.slayout.addWidget(self.afterDelayPieChart(), QtCore.Qt.AlignCenter)


    # combo box items
    def onActivated(self, text):
        # print(text)
        if text == 'Linked Bags':
            if self.flag:
                self.removeWidgets2()
            else:
                self.removeWidgets()
            # self.layout.addLayout(self.chartLayout)                     # add chartLayout 2/13 9:16
            # self.chartLayout.addWidget(self.createBar())
            # self.removeWidgets2()                       # now it works for summary bar with label
            # self.layout.removeItem(self.slayout)

            self.layout.addWidget(self.createBar())
            self.flag = False

        elif text == 'Unlinked Bags':
            if self.flag:
                self.removeWidgets2()
            else:
                self.removeWidgets()
            print("before unlinked bag",self.layout.count())
            self.layout.addWidget(self.createUnlinkedBar())
            print("after unlinked bag",self.layout.count())
            self.flag = False

        elif text == 'Summary':
            if self.flag:
                self.removeWidgets2()
            else:
                self.removeWidgets()
            self.chartLayout = QHBoxLayout()
            self.summaryLabel = QtWidgets.QLabel()
            # self.summaryLabel.setText("tettddddddddddddddddddtt")
            self.setSummaryLabel()
        
            self.chartLayout.addWidget(self.createSummaryBar())
            self.chartLayout.addWidget(self.summaryLabel)
            print("before add layout",self.layout.count())
            self.layout.addLayout(self.chartLayout)
            print("after add layout",self.layout.count())
            self.flag = True

    def setSummaryLabel(self):
        try:
            total = len(self.dfinal.index)      # total number of scanned bags
            linked = len(self.linked.index)     # total number of linked bags
            unlinked = total - linked           # total number of unlinked bags
            co_count = len(self.cut_oversized.index)   # cut or oversized bags.
            co_percentage = (co_count/total) * 100     # cut or oversized percentage
            co_unlinked_percentage = (co_count/unlinked) * 100
            percentage = (unlinked/(total)) * 100       # percentage for unlinked bags
            slipping = len(self.slipping.index)
            s_percentage = (slipping/total) * 100
            pushed = len(self.pushed.index)
            p_percentage = (pushed/total) * 100

            self.summaryLabel.setText('Bin Tracking Infomation:\nTotal Bins: {0}\nTotal Linked Bins: {1}\nTotal Unlinked Bins: {2}\nPercent of Unlinked Bins: {3:.2f} % \
                \nSlipping Bins: {4}\nPercent of Slipping Bins: {5:.2f} % \nPushed Bins: {6}\nPercent of Pushed Bins: {7:.2f} %\n'.format(total, linked, unlinked, \
                    percentage, slipping, s_percentage, pushed, p_percentage))
            self.summaryLabel.setText(self.summaryLabel.text() + "\nUnlinked Bin Tracking: \nCut/oversized object: {0}\nPercentage (unlinked): {1:.2f} %\
                \nPercentage (total): {2:.2f} %".format(co_count, co_unlinked_percentage, co_percentage))
            self.summaryLabel.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
        except AttributeError:
            self.statusbar.showMessage("Data not processed")        # not shown due to covered by top message


    def simulate(self):
        # print(self.text.text())
        if bool(re.match('^[0-9]+$',self.text.text())):           
            try:
                self.tm = TimeMeasure('runtime_.txt', int(self.text.text()))		# change variables to global value 2/11 2:06
                self.tm.getDuration()
                self.tm.runList("")
                self.tm.stopList("")
                self.tm.runListDelay("")
                self.tm.stopListDelay("")
                self.total_time = self.tm.org_finish_time - self.tm.org_start_time
                self.statusbar.showMessage("Done")
            except FileNotFoundError:
                self.statusbar.showMessage("Data not ready")                       

            
            # self.labelDelay.setText("Simulation Result:\n")
            # self.labelDelay.setText(self.labelDelay.text() + "\n---------------Before delay---------------\n\n")
            # self.labelDelay.setText(self.labelDelay.text() + "Run Time total: {0:d} Sum: {1:f} seconds Percentage: {2:.2f}%\n".format(len(self.tm.total_running_time), sum(self.tm.total_running_time), sum(self.tm.total_running_time)/self.total_time * 100))
            # self.labelDelay.setText(self.labelDelay.text() + "Stop Time total: {0:d} Sum: {1:f} seconds Percentage: {2:.2f}%\n".format(len(self.tm.total_stopped_time), sum(self.tm.total_stopped_time), sum(self.tm.total_stopped_time)/self.total_time * 100))
            # self.labelDelay.setText(self.labelDelay.text() + "Total: {0:f} seconds Percentage: {1:.2f}%\n".format(self.total_time, sum(self.tm.total_running_time)/self.total_time * 100 + sum(self.tm.total_stopped_time)/self.total_time * 100))
            # # print("run:",len(tm.total_running_time), "sum:", sum(tm.total_running_time),"percentage:",sum(tm.total_running_time)/total_time * 100)
            # # print("stop:",len(tm.total_stopped_time), "sum:", sum(tm.total_stopped_time),"percentage:",sum(tm.total_stopped_time)/total_time * 100)
            # # print("total:",total_time, sum(tm.total_running_time)/total_time * 100 + sum(tm.total_stopped_time)/total_time * 100)
            # # print("\n---------------Add delay 2 seconds---------------\n")
            # self.labelDelay.setText(self.labelDelay.text() + "\n---------------Add delay 2 seconds---------------\n\n")
            
            # self.total_time_after_delay = self.tm.delay_finish_time - self.tm.delay_start_time
            # self.labelDelay.setText(self.labelDelay.text() + "Run time after delay: {0:d} Sum: {1:f} seconds Percentage: {2:.2f}%\n".format(len(self.tm.total_running_after_delay), sum(self.tm.total_running_after_delay), sum(self.tm.total_running_after_delay) / self.total_time_after_delay * 100))
            # self.labelDelay.setText(self.labelDelay.text() + "Stop time after delay: {0:d} Sum: {1:f} seconds Percentage: {2:.2f}%\n".format(len(self.tm.total_stopped_after_delay), sum(self.tm.total_stopped_after_delay), sum(self.tm.total_stopped_after_delay) / self.total_time_after_delay * 100))
            # self.labelDelay.setText(self.labelDelay.text() + "Total: {0:f} seconds Percentage: {1:.2f}%\n".format(self.total_time_after_delay, sum(self.tm.total_running_after_delay) / self.total_time_after_delay * 100 + sum(self.tm.total_stopped_after_delay) / self.total_time_after_delay * 100))
            # # print("run after delay:", len(tm.total_running_after_delay), "sum:", sum(tm.total_running_after_delay), "percentage:",sum(tm.total_running_after_delay) / total_time_after_delay * 100)
            # # print("stop after delay:",len(tm.total_stopped_after_delay), "sum:", sum(tm.total_stopped_after_delay), "percentage:",sum(tm.total_stopped_after_delay) / total_time_after_delay * 100)
            # # print("total:",total_time_after_delay, sum(tm.total_running_after_delay) / total_time_after_delay * 100 + sum(tm.total_stopped_after_delay) / total_time_after_delay * 100)

            # self.tm.fakestopList()
            # self.delaylist = self.tm.getCertainRangeList(self.tm.fake_total_stopped_time)
            # # print("\nSummary:")
            # # print("Before delay XRAY_MIN / total: 100% ----> After delay XRAY_MIN / total: {0:.2f}%".format((len(tm.fake_total_stopped_time)-len(delaylist))/len(tm.fake_total_stopped_time)*100))
            # # print("Before delay total time: 100% ----> After delay total time: {0:.2f}%".format(total_time_after_delay/total_time*100))
            # self.labelDelay.setText(self.labelDelay.text() + "\nSummary:")
            # self.labelDelay.setText(self.labelDelay.text() + "Before delay total time: 100% ----> After delay total time: {0:.2f}%\n".format(self.total_time_after_delay/self.total_time*100))
            # self.labelDelay.setText(self.labelDelay.text() + "Before delay XRAY_MIN / total: 100% ----> After delay XRAY_MIN / total: {0:.2f}%".format((len(self.tm.fake_total_stopped_time)-len(self.delaylist))/len(self.tm.fake_total_stopped_time)*100))
            # self.labelDelay.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
            # self.labelDelay.setAlignment(Qt.AlignTop)#HCenter)

            # self.removeWidgets1()
            # self.slayout.addWidget(self.beforeDelayDistribution(), QtCore.Qt.AlignCenter)
            # self.slayout.addWidget(self.afterDelayDistribution(), QtCore.Qt.AlignCenter)


    # display summary label
    def setSummary(self):
    	self.image.setPixmap(QtGui.QPixmap('his.png'))

    # display linked bags histogram
    def setLinkedHistogram(self):
        # pixmap = pixmap.tmaled(self.label.width(), self.label.height(), QtCore.Qt.KeepAspectRatio, QtCore.Qt.FastTransformation)	# make image unclear
        self.image.setPixmap(QtGui.QPixmap('link.png'))

    # display unlinked bags histogram
    def setUnlinkedHistogram(self):
        self.image.setPixmap(QtGui.QPixmap('unlink.png'))

    # display time stopped histogram
    def setTimeStoppedHistogram(self):
        self.image.setPixmap(QtGui.QPixmap('stop_time_distribution.png'))

    # display time running histogram
    def setTimeRunningHistogram(self):
        self.image.setPixmap(QtGui.QPixmap('running_time_distribution'))

    # open file dialog
    def openFile(self):
        filenames, _ = QtWidgets.QFileDialog.getOpenFileNames(None,"QFileDialog.getOpenFileNames()", "","All Files (*);;Log Files (*.log);;")
        if filenames:
            print("inside:",filenames)
        print("fdsfs", filenames)

        illegal = False
        suf = 'log' # test for single .txt first, need to modify for final version
        if len(filenames) != 0:
            for f in filenames: # check all files are illegal in here
                suffix = f[f.rfind('.')+1:]
                if suffix != suf:
                    print("Illegal selection")
                    illegal = True
            print(illegal)
            if illegal:
                self.showdialog(illegal, True);
            else:
                # self.statusbar.showMessage('Processing Files...')
                start_time = timeit.default_timer()
                pp = PreProc(filenames)     # pass files into PreProc class
                elapsed = timeit.default_timer() - start_time
                print("time cost preProc:", elapsed)
                # self.statusbar.showMessage('Analyzing datas...')
                start_time1 = timeit.default_timer()
                dp = DataProc()     # pass the prepared data into DataProc class
                elapsed1 = timeit.default_timer() - start_time1
                print("time cost dataProc:", elapsed1)
                self.linked = dp.linked
                self.unlinked = dp.unlinked
                self.dfinal = dp.dfinal
                self.cut_oversized = dp.cut_oversized
                self.slipping = dp.slipping
                self.pushed = dp.pushed
                self.statusbar.showMessage('Done')
                # if self.flag:
                #     self.removeWidgets2()
                # else:
                #     self.removeWidgets()
                # self.layout.addWidget(self.createBar())


    # open directory dialog
    def openDir(self):
        dialog = QtWidgets.QFileDialog()
        dialog.setFileMode(QFileDialog.DirectoryOnly)

        dic_file = []
        if dialog.exec_(): # == QtGui.QDialog.Accepted:
            dic_file = dialog.selectedFiles()
        print("openDir: (dic_file) ", dic_file)

        log_file = []
        has_log = False
        suf = 'log'
        if dic_file:
            for f in os.listdir(dic_file[0]):
                suffix = f[f.rfind('.')+1:]
                name = f[:f.rfind('.')]
                print(name)
                if suffix == suf:
                    has_log = True
                    if "AnalogicStandaloneType" in name:# if match AnalogicStandaloneType*.log, append to log_file
                        log_file += dic_file[0]+"/"+f,
            print(has_log, log_file)
            if not has_log:            
                self.showdialog(False, has_log)
            if len(log_file) == 0 and has_log:
                self.showdialog(False, False)
            if len(log_file) != 0:
                start_time = timeit.default_timer()
                pp = PreProc(log_file)     # pass files into PreProc class
                elapsed = timeit.default_timer() - start_time
                print("time cost preProc:", elapsed)
                start_time1 = timeit.default_timer()
                dp = DataProc()     # pass the prepared data into DataProc class
                elapsed1 = timeit.default_timer() - start_time1
                print("time cost dataProc:", elapsed1)
                self.linked = dp.linked
                self.unlinked = dp.unlinked
                self.dfinal = dp.dfinal
                self.cut_oversized = dp.cut_oversized
                self.slipping = dp.slipping
                self.pushed = dp.pushed
                self.statusbar.showMessage('Done')
                # if self.flag:
                #     self.removeWidgets2()
                # else:
                #     self.removeWidgets()
                # self.layout.addWidget(self.createBar())


    # pop up warning window
    def showdialog(self, illegal_file, has_log):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        if not has_log:
            msg.setText("No log files found.")
        if illegal_file:
            print("in illegal")
            msg.setText("Invalid log files detected.")

        msg.setWindowTitle("Something's wrong")
        # msg.setGeometry(200, 200, 300, 400) # need to change if need this line
        msg.setStandardButtons(QMessageBox.Ok)

        retval = msg.exec_()


    def exit(self):
        sys.exit(app.exec_())
コード例 #25
0
class GUI_HyperParameters(QWidget):
    def __init__(self, gui_play, cur_hps=None):
        super().__init__()
        self.gui_play = gui_play
        self.name_inpt_dict = {}
        self.structured_hyperparams = {}
        self.substructered_items = []
        self.reference_hps = hp.AgentsHyperparameters()
        if cur_hps is None:
            self.hp = hp.AgentsHyperparameters()
        else:
            self.hp = cur_hps
        self.initUI()

    def initUI(self):
        self.resize(800, 600)
        self.center()
        self.setWindowTitle('Icon')
        self.setWindowIcon(QIcon('test.png'))

        self.v_main = QVBoxLayout()
        idx = 0
        for attr in dir(self.hp):
            attr_name = str(attr)
            if not callable(getattr(self.hp,
                                    attr)) and not attr.startswith("__"):
                idx += 1
                hbox = QHBoxLayout()
                lab = QLabel(attr_name, self)
                hbox.addWidget(lab)
                the_attrib = getattr(self.hp, attr_name)
                if isinstance(the_attrib, dict):
                    inp = QComboBox()
                    inp.addItems(the_attrib.keys())
                    self.structured_hyperparams[attr_name] = (idx, the_attrib)
                    inp.activated.connect(self.activated_combobox)
                    hbox.addWidget(inp)
                elif isinstance(the_attrib, list):
                    list_key = the_attrib[0]
                    reference = getattr(self.reference_hps, attr_name)
                    if isinstance(reference, dict):
                        if list_key in reference:
                            reference[list_key] = the_attrib[1]
                            inp = QComboBox()
                            inp.addItems(reference.keys())
                            self.structured_hyperparams[attr_name] = (
                                idx, reference)
                            inp.activated.connect(self.activated_combobox)
                            hbox.addWidget(inp)
                        else:
                            inp = None
                    else:
                        inp = None
                else:
                    inp = QLineEdit(str(the_attrib), self)
                    hbox.addWidget(inp)
                if inp is not None:
                    self.name_inpt_dict[attr_name] = inp
                    self.v_main.addLayout(hbox)
        self.add_sub_inputs()

        self.start_btn = QPushButton("start", self)
        self.start_btn.clicked.connect(self.train_click)
        self.v_main.addWidget(self.start_btn)

        self.setLayout(self.v_main)
        self.show()

    def add_sub_inputs(self):
        items_per_row = 3
        for sub_struct in self.substructered_items:
            for i in range(self.v_main.count()):
                layout_item = self.v_main.itemAt(i)
                if isinstance(
                        layout_item,
                        QHBoxLayout) and layout_item.layout() == sub_struct:
                    clear_layout(layout_item)
                    self.v_main.removeItem(layout_item)
        self.substructered_items.clear()
        for struct_hyper_key in self.structured_hyperparams.keys():
            combo_box = self.name_inpt_dict[struct_hyper_key]
            new_items_dict = self.structured_hyperparams[struct_hyper_key][1][
                combo_box.currentText()]
            new_item_keys = list(new_items_dict.keys())
            for i in range(0, len(new_item_keys), items_per_row):
                h_outer = QHBoxLayout()
                for j in range(items_per_row):
                    if i + j < len(new_item_keys):
                        cur_key = new_item_keys[i + j]
                        hbox = QHBoxLayout()
                        hbox.addWidget(QLabel(cur_key, self))
                        inp = QLineEdit(str(new_items_dict[cur_key]), self)
                        hbox.addWidget(inp)
                        self.name_inpt_dict[cur_key] = inp
                        h_outer.addLayout(hbox)
                self.substructered_items.append(h_outer)
                self.v_main.insertLayout(
                    self.structured_hyperparams[struct_hyper_key][0], h_outer)

    def activated_combobox(self):
        print("connected")
        self.add_sub_inputs()

    def closeEvent(self, event):
        event.accept()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    @pyqtSlot()
    def train_click(self):
        for attr in dir(self.hp):
            if not callable(getattr(self.hp,
                                    attr)) and not attr.startswith("__"):
                attr_nam = str(attr)
                if isinstance(self.name_inpt_dict[attr_nam], QComboBox):
                    combo_box = self.name_inpt_dict[attr_nam]
                    selected_item = combo_box.currentText()
                    items_dict = self.structured_hyperparams[attr_nam][1][
                        selected_item]
                    for cur_key in items_dict.keys():
                        value = get_int_or_else_float_from_str(
                            self.name_inpt_dict[cur_key].text())
                        if value is not None:
                            items_dict[cur_key] = value
                    print(items_dict)
                    setattr(self.hp, attr_nam, (selected_item, items_dict))
                    print(getattr(self.hp, attr_nam))
                else:
                    value = get_int_or_else_float_from_str(
                        self.name_inpt_dict[attr_nam].text())
                    if value is not None:
                        setattr(self.hp, attr_nam, value)
        self.gui_play.new_handler_and_start(self.hp)
        self.hide()
コード例 #26
0
class Main(Widget, QWidget):
    def __init__(self, widget_manager, info):
        # init
        Widget.__init__(self, widget_manager, info)
        QWidget.__init__(self)
        self.conf = {}
        self.lang = info.lang
        self.settings_win = None
        # setup window
        with open(os.path.join(RES, 'timer', 'style.css'),
                  encoding='utf-8') as file:
            self.setStyleSheet(file.read())
        # setup menu
        self.menu = QMenu(self)
        start_action = self.menu.addAction(QIcon(PLAY), self.lang['start'])
        start_action.triggered.connect(self._start)
        pause_action = self.menu.addAction(QIcon(PAUSE), self.lang['pause'])
        pause_action.triggered.connect(self._pause)
        reset_action = self.menu.addAction(QIcon(STOP), self.lang['reset'])
        reset_action.triggered.connect(self._reset)
        # all setups
        self.timer = QTimer(self)
        self.timer.timeout.connect(self._tick)
        self._last = 0
        self.list = []
        self.shows = {}
        self.v_box = QVBoxLayout(self)
        self.v_box.setContentsMargins(0, 0, 0, 0)
        self.v_box.setSpacing(1)
        self.setLayout(self.v_box)
        # constants
        self.TICK = os.path.join(RES, 'timer', 'tick.ogg')
        self.TACK = os.path.join(RES, 'timer', 'tack.ogg')
        self.ALARM = os.path.join(RES, 'timer', 'alarm.ogg')

    @try_except()
    def _add_timer(self, h=0, m=0, s=0, enabled=True):
        lcd = QLCDNumber(self), QLCDNumber(self), QLCDNumber(self)
        for i in range(3):
            lcd[i].display((h, m, s)[i])
            lcd[i].setDigitCount(2)
            lcd[i].setSegmentStyle(QLCDNumber.Flat)
            lcd[i].setEnabled(enabled)
        h_box = QHBoxLayout()
        h_box.setContentsMargins(0, 0, 0, 0)
        h_box.setSpacing(0)
        h_box.addWidget(lcd[0])
        h_box.addWidget(lcd[1])
        h_box.addWidget(lcd[2])
        self.v_box.addLayout(h_box)
        # ------ 0 ------------ 1 -------- 2 -------- 3 -------- 4 ---
        # (lcd, lcd, lcd), QHBoxLayout, is past, is enabled, (h, m, s)
        self.list.append((lcd, h_box, True, enabled, (h, m, s)))

    def _delete_timer(self, index):
        self.v_box.removeItem(self.list[index][1])
        del self.list[index]
        self._reset()  # render bug not fixed :(

    @try_except()
    def _turn_enabled(self, index, enabled):
        item = self.list[index]
        for lcd in item[0]:
            lcd.setEnabled(enabled)
        self.list[index] = item[0], item[1], item[2], enabled, item[4]

    @try_except()
    def _tick(self):
        ticked = False
        sec = math.floor(time.time() - self._last)  # amplify precision
        if not sec:
            return
        for n in range(len(self.list)):
            item = self.list[n]
            if not item[3]:
                continue
            for i in range(int(sec)):
                if not item[0][2].value():
                    if item[0][1].value() or item[0][0].value():
                        item[0][2].display(59)
                        if item[0][1].value():
                            item[0][1].display(item[0][1].value() - 1)
                        else:
                            item[0][1].display(59)
                            item[0][0].display(item[0][0].value() - 1)
                else:
                    item[0][2].display(item[0][2].value() - 1)
                if not item[0][2].value() and not item[0][1].value() \
                        and not item[0][0].value() and item[2]:
                    self._alarm(n)
                    self.list[n] = item[0], item[1], False, item[3], item[4]
                else:
                    ticked = True
        if ticked:
            self._last += 1  # amplify precision
            self._sec_sound()
        else:
            self.timer.stop()

    @try_except()
    def _play(self, file, volume):  # strange, big memory leak and crash
        player = QMediaPlayer(self)
        player.setMedia(QMediaContent(QUrl.fromLocalFile(file)))
        player.setVolume(volume)
        player.play()

    @try_except()
    def _sec_sound(self):
        if not strtobool(self.conf['seconds']):
            return
        volume = int(self.conf['seconds_volume'])
        if int(math.floor(time.time())) % 2 == 0:
            self._play(self.TICK, volume)
        else:
            self._play(self.TACK, volume)

    @try_except()
    def _alarm(self, index):
        if strtobool(self.conf['alarm']):
            self._play(self.ALARM, int(self.conf['alarm_volume']))
        if strtobool(self.conf['alert']):
            self._show_timeout(index)
        if strtobool(self.conf['notify']):
            self.widget_manager.main_gui.main.tray.showMessage(
                self.lang['notify_title'],
                self.lang['notify_mess'].format(self.get_timer_text(index)),
                QSystemTrayIcon.Information, int(self.conf['notify_msec']))

    @try_except()
    def _show_timeout(self, index):
        if index in self.shows:
            return
        self.shows[index] = Timeout(self, self.get_timer_text(index), index)

    @try_except()
    def _start(self, checked):
        self._last = time.time()
        self.timer.start(int(self.conf['tick_ms']))  # amplify precision

    @try_except()
    def _pause(self, checked):
        self.timer.stop()

    @try_except()
    def _reset(self, checked=False):
        self.timer.stop()
        for timer in self.list:
            self.v_box.removeItem(timer[1])
        self._save_timers()
        self.list.clear()
        self._load_timers()
        self.layout().update()

    def _load_timers(self):
        if ('timers' not in self.conf) or self.conf['timers'] == '[]' or \
                not self.conf['timers']:
            self._add_timer()
            return
        for data in json.loads(self.conf['timers']):
            self._add_timer(*data)

    def _save_timers(self):
        if not self.conf:
            return
        timers = []
        for timer in self.list:
            timers.append((timer[4][0], timer[4][1], timer[4][2], timer[3]))
        self.conf['timers'] = json.dumps(timers)

    def _setup_conf(self):
        self.conf = self.widget_manager.get_config(self.info.NAME)
        if 'alarm' not in self.conf:
            self.conf['alarm'] = 'True'
        if 'alert' not in self.conf:
            self.conf['alert'] = 'True'
        if 'notify' not in self.conf:
            self.conf['notify'] = 'True'
        if 'notify_msec' not in self.conf:
            self.conf['notify_msec'] = str(10000)
        if 'seconds' not in self.conf:
            self.conf['seconds'] = 'False'
        if 'alarm_volume' not in self.conf:
            self.conf['alarm_volume'] = str(100)
        if 'seconds_volume' not in self.conf:
            self.conf['seconds_volume'] = str(100)
        if 'tick_ms' not in self.conf:
            self.conf['tick_ms'] = str(10)

    def place(self):
        self._setup_conf()
        self._load_timers()

    def boot(self):
        self._setup_conf()
        self._load_timers()

    def unload(self):
        self._save_timers()

    @try_except()
    def show_settings(self):
        self.settings_win = Settings(self)

    @try_except()
    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            self.menu.exec(event.globalPos())

    @try_except()
    def mouseDoubleClickEvent(self, event):
        index = int(event.pos().y() / (self.height() / (len(self.list))))
        self._turn_enabled(index, not self.list[index][3])

    def get_timer_text(self, index) -> str:
        timer = str(self.list[index][4][0]) + ':'
        timer += str(self.list[index][4][1]) + ':'
        timer += str(self.list[index][4][2])
        return timer
コード例 #27
0
ファイル: views.py プロジェクト: reinhaaard13/Hariku-App
class HomeScreen(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Home Screen")
        self.resize(550, 461)
        self.setStyleSheet(Hariku_Style.get_window_stylesheet())
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)

        self.setupUI()

    def setupUI(self):
        self.setWindowIcon(Hariku_Style.getIcon())

        self.centralwidget = QWidget(self)
        self.setFocus()

        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")

        self.topcenter_layout = QHBoxLayout()

        spacerItem = QSpacerItem(25, 20, QSizePolicy.MinimumExpanding,
                                 QSizePolicy.Minimum)
        self.topcenter_layout.addItem(spacerItem)

        self.monthFilter = QDateEdit(self.centralwidget)
        self.monthFilter.setCurrentSection(QDateTimeEdit.MonthSection)
        self.monthFilter.setButtonSymbols(QSpinBox.NoButtons)
        self.monthFilter.setDate(datetime.now())
        self.monthFilter.setDisplayFormat("MMMM/yyyy")
        self.monthFilter.setFont(Hariku_Style.get_font(10))
        self.monthFilter.setStyleSheet(Hariku_Style.get_dateedit_stylesheet())
        self.monthFilter.dateChanged.connect(self.filterDiaryByMonth)
        self.topcenter_layout.addWidget(self.monthFilter)

        self.showAllBtn = QPushButton("Remove Filter", self.centralwidget)
        self.showAllBtn.setFont(Hariku_Style.get_font(8))
        self.showAllBtn.clicked.connect(self.getDiaries)
        self.showAllBtn.setStyleSheet(
            Hariku_Style.get_moodBtn_stylesheet("rgb(38, 160, 173)",
                                                "rgb(8, 102, 112)"))
        self.topcenter_layout.addWidget(self.showAllBtn)

        spacerItem1 = QSpacerItem(25, 20, QSizePolicy.MinimumExpanding,
                                  QSizePolicy.Minimum)
        self.topcenter_layout.addItem(spacerItem1)

        self.gridLayout.addLayout(self.topcenter_layout, 1, 0, 1, 1)

        self.bottomLayout = QHBoxLayout()

        spacerItem2 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                  QSizePolicy.Minimum)
        self.bottomLayout.addItem(spacerItem2)

        self.createBtn = QPushButton("+ Add New Diary", self.centralwidget)
        self.createBtn.setFont(Hariku_Style.get_font(10))
        self.createBtn.clicked.connect(self.addNewDiary)
        self.createBtn.setStyleSheet(
            Hariku_Style.get_moodBtn_stylesheet("rgb(40, 186, 130)",
                                                "rgb(207, 207, 188)"))
        self.bottomLayout.addWidget(self.createBtn)

        self.gridLayout.addLayout(self.bottomLayout, 4, 0, 1, 1)

        self.contentScrollArea = QScrollArea(self.centralwidget)
        self.contentScrollArea.setEnabled(True)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.contentScrollArea.sizePolicy().hasHeightForWidth())
        self.contentScrollArea.setSizePolicy(sizePolicy)
        self.contentScrollArea.setStyleSheet(
            Hariku_Style.get_scrollarea_stylesheet())
        self.contentScrollArea.setWidgetResizable(True)
        self.contentScrollArea.setAlignment(QtCore.Qt.AlignLeading
                                            | QtCore.Qt.AlignLeft
                                            | QtCore.Qt.AlignTop)

        self.scrollAreaWidgetContents = QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 487, 321))
        self.scrollAreaLayout = QVBoxLayout(self.scrollAreaWidgetContents)

        self.getDiaries()

        self.contentScrollArea.setWidget(self.scrollAreaWidgetContents)

        self.gridLayout.addWidget(self.contentScrollArea, 2, 0, 1, 1)

        self.judul = QLabel("\nWelcome Home:)\n", self)
        self.judul.setFont(Hariku_Style.get_font(18))
        self.judul.setAlignment(QtCore.Qt.AlignCenter)
        self.gridLayout.addWidget(self.judul, 0, 0, 1, 1)

        self.setCentralWidget(self.centralwidget)

    def addNewDiary(self):
        dialog = DiaryScreen(self)
        dialog.show()
        self.hide()

    def clearScrollAreaLayout(self):
        # delete the diaries currently showind
        for i in reversed(range(self.scrollAreaLayout.count())):
            try:
                self.scrollAreaLayout.itemAt(i).widget().setParent(None)
            except AttributeError:
                self.scrollAreaLayout.removeItem(
                    self.scrollAreaLayout.itemAt(i))

    def filterDiaryByMonth(self):
        self.clearScrollAreaLayout()

        year = self.monthFilter.date().year()
        month = self.monthFilter.date().month()

        diaries = getDiaryByMonth(year, month)

        for i, diary in enumerate(diaries):
            self.diaryItem = QWidget(self.scrollAreaWidgetContents)
            sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
            sizePolicy.setHeightForWidth(
                self.diaryItem.sizePolicy().hasHeightForWidth())
            self.diaryItem.setSizePolicy(sizePolicy)
            self.diaryItem.setMinimumSize(QtCore.QSize(0, 50))
            self.diaryItem.setStyleSheet(
                "background-color: rgba(227, 217, 163, 100%);\nborder-radius : 10px;"
            )
            self.diaryItem.setObjectName("diaryItem")
            self.itemLayout = QGridLayout(self.diaryItem)

            self.contentDateLayout = QVBoxLayout()
            self.contentDateLayout.setObjectName("contentDateLayout")

            self.content = QLabel(self.truncateString(diary.content),
                                  self.diaryItem)
            self.content.setFont(Hariku_Style.get_font(10))
            self.contentDateLayout.addWidget(self.content)

            self.date = QLabel(
                diary.date.strftime("%d %B %Y") +
                diary.time.strftime("  %I:%M %p"), self.diaryItem)
            self.date.setFont(Hariku_Style.get_font(8))
            self.contentDateLayout.addWidget(self.date)

            self.itemLayout.addLayout(self.contentDateLayout, 0, 0, 1, 1)

            self.buttons.append(i)
            self.buttons[i] = [
                QPushButton("⋗", self.diaryItem),
                QPushButton("×", self.diaryItem)
            ]

            self.buttons[i][0].clicked.connect(
                lambda checked, i=diary.diary_id: self.viewDiaryById(i))
            sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(
                self.buttons[i][0].sizePolicy().hasHeightForWidth())
            self.buttons[i][0].setSizePolicy(sizePolicy)
            self.buttons[i][0].setFont(Hariku_Style.get_font(9))
            self.buttons[i][0].setStyleSheet(
                Hariku_Style.get_moodBtn_stylesheet("rgb(145, 133, 63)",
                                                    "rgb(235, 224, 157)"))
            self.itemLayout.addWidget(self.buttons[i][0], 0, 1, 1, 1)

            # self.deleteBtn = QPushButton("×", self.diaryItem)
            self.buttons[i][1].clicked.connect(
                lambda checked, i=diary.diary_id: self.deleteDiaryById(i))
            sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(
                self.buttons[i][1].sizePolicy().hasHeightForWidth())
            self.buttons[i][1].setSizePolicy(sizePolicy)
            self.buttons[i][1].setFont(Hariku_Style.get_font(9))
            self.buttons[i][1].setStyleSheet(
                Hariku_Style.get_moodBtn_stylesheet("rgb(145, 63, 63)",
                                                    "rgb(235, 157, 157)"))
            self.itemLayout.addWidget(self.buttons[i][1], 0, 2, 1, 1)

            self.scrollAreaLayout.addWidget(self.diaryItem,
                                            alignment=QtCore.Qt.AlignTop)

        spacerItem2 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.MinimumExpanding)
        self.scrollAreaLayout.addItem(spacerItem2)

    def getDiaries(self):
        diaries = getAllDiaries()

        self.monthFilter.setDate(datetime.now())
        self.clearScrollAreaLayout()

        self.buttons = []

        for i, diary in enumerate(diaries):
            self.diaryItem = QWidget(self.scrollAreaWidgetContents)
            sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
            sizePolicy.setHeightForWidth(
                self.diaryItem.sizePolicy().hasHeightForWidth())
            self.diaryItem.setSizePolicy(sizePolicy)
            self.diaryItem.setMinimumSize(QtCore.QSize(0, 50))
            self.diaryItem.setStyleSheet(
                "background-color: rgba(227, 217, 163, 100%);\nborder-radius : 10px;"
            )
            self.diaryItem.setObjectName("diaryItem")
            self.itemLayout = QGridLayout(self.diaryItem)

            self.contentDateLayout = QVBoxLayout()
            self.contentDateLayout.setObjectName("contentDateLayout")

            self.content = QLabel(self.truncateString(diary.content),
                                  self.diaryItem)
            self.content.setFont(Hariku_Style.get_font(10))
            self.contentDateLayout.addWidget(self.content)

            self.date = QLabel(
                diary.date.strftime("%d %B %Y") +
                diary.time.strftime("  %I:%M %p"), self.diaryItem)
            self.date.setFont(Hariku_Style.get_font(8))
            self.contentDateLayout.addWidget(self.date)

            self.itemLayout.addLayout(self.contentDateLayout, 0, 0, 1, 1)

            self.buttons.append(i)
            self.buttons[i] = [
                QPushButton("⋗", self.diaryItem),
                QPushButton("×", self.diaryItem)
            ]

            self.buttons[i][0].clicked.connect(
                lambda checked, i=diary.diary_id: self.viewDiaryById(i))
            sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(
                self.buttons[i][0].sizePolicy().hasHeightForWidth())
            self.buttons[i][0].setSizePolicy(sizePolicy)
            self.buttons[i][0].setFont(Hariku_Style.get_font(9))
            self.buttons[i][0].setStyleSheet(
                Hariku_Style.get_moodBtn_stylesheet("rgb(145, 133, 63)",
                                                    "rgb(235, 224, 157)"))
            self.itemLayout.addWidget(self.buttons[i][0], 0, 1, 1, 1)

            # self.deleteBtn = QPushButton("×", self.diaryItem)
            self.buttons[i][1].clicked.connect(
                lambda checked, i=diary.diary_id: self.deleteDiaryById(i))
            sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(
                self.buttons[i][1].sizePolicy().hasHeightForWidth())
            self.buttons[i][1].setSizePolicy(sizePolicy)
            self.buttons[i][1].setFont(Hariku_Style.get_font(9))
            self.buttons[i][1].setStyleSheet(
                Hariku_Style.get_moodBtn_stylesheet("rgb(145, 63, 63)",
                                                    "rgb(235, 157, 157)"))
            self.itemLayout.addWidget(self.buttons[i][1], 0, 2, 1, 1)

            self.scrollAreaLayout.addWidget(self.diaryItem,
                                            alignment=QtCore.Qt.AlignTop)

        spacerItem2 = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.MinimumExpanding)
        self.scrollAreaLayout.addItem(spacerItem2)

    def truncateString(self, string):
        try:
            string = string.replace('\n', ' ')
            return string[:45] + '...'
        except IndexError:
            return string

    def viewDiaryById(self, id):
        dialog = DiaryScreen(self, edit=False, id=id)
        dialog.show()
        self.hide()

    def deleteDiaryById(self, id):
        deleteDiaryById(id)
        self.clearScrollAreaLayout()
        self.getDiaries()
コード例 #28
0
ファイル: paint.py プロジェクト: ShiraStarL/Graphics_HW3
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # Create menu bar
        self.CreateMenuBar()

        # Create the drawing canvas
        self.canvas = DrawCanvas()
        self.TransformationImage = TransformationImage(self.canvas.Draw)

        # Create the main window widget
        self.widget = QWidget()
        self.DrawWidget = QWidget()
        self.TransformationWidget = QWidget()

        # Create both main modes layouts
        self.TransformationLayout = QVBoxLayout()
        self.DrawLayout = QVBoxLayout()

        # Set default transformation mode to False
        self.isTransformationMode = False

        # Add draw modes buttons to draw layout
        self.DrawPalette = QHBoxLayout()
        self.AddModesButtons(self.DrawPalette)
        self.DrawLayout.addLayout(self.DrawPalette)

        # Add window transformations modes buttons to transformation layout
        self.TransformationsPalette = QHBoxLayout()
        self.AddTransformationsButtons(self.TransformationsPalette)
        self.TransformationLayout.addLayout(self.TransformationsPalette)

        # Add the drawing canvas to both layouts
        self.DrawLayout.addWidget(self.canvas)

        # Add window colors buttons to draw layout
        self.colorPalette = QHBoxLayout()
        self.AddColorButtons(self.colorPalette)
        self.DrawLayout.addLayout(self.colorPalette)

        # Create the main window widgets
        self.DrawWidget.setLayout(self.DrawLayout)
        self.TransformationWidget.setLayout(self.TransformationLayout)

        # Create centeral widget to hold our widget
        self.centralwidget = QWidget(self)

        # Insert our wigets to stackwidget
        self.stackedWidget = QStackedWidget(self.centralwidget)
        self.stackedWidget.addWidget(self.DrawWidget)
        self.stackedWidget.addWidget(self.TransformationWidget)

        # Set the window and default widget as DrawWidget
        self.setCentralWidget(self.centralwidget)

        # Set size and prevent from user change size
        self.setFixedSize(1300, 830)

    # Build colors buttons
    def AddColorButtons(self, palette):
        # for each color type make a button in this color
        for color in COLORS:
            button = QPaletteButton(color)
            # Connect the button to setColor function
            button.pressed.connect(
                lambda color=color: self.canvas.setColor(color))
            # Add the buttun to layout widget
            palette.addWidget(button)

    # Update button text and change widht
    def WidhtSelected(self, width):
        widthNum = int(width.split(' ')[0])
        self.canvas.setWidth(widthNum)
        self.widthBtn.setText(str(self.canvas.currentWidth) + 'px')

    # Create pen width menu
    def AddWidthMenu(self):
        menu = QMenu()
        # Get row on menu for each PEN_WIDTHS
        for width in PEN_WIDTHS:
            # Connect menu option to setWidth function
            menu.addAction(width,
                           lambda width=width: self.WidhtSelected(width))
            menu.addSeparator()
        # Return menu
        return menu

    # Build modes buttons
    def AddModesButtons(self, palette):
        # For each mode type make a button in this mode
        for mode in MODES:
            button = ModesButton(mode)

            if mode == 'Pen Width':
                button.setMenu(self.AddWidthMenu())
                button.setText(str(self.canvas.currentWidth) + 'px')
                self.widthBtn = button
            elif mode == 'Transformation':
                # Connect Transformation button to FlipTransformationMode
                button.pressed.connect(self.FlipTransformationMode)
            elif mode == 'Undo':
                # Connect undo button to undo function
                button.pressed.connect(self.canvas.undo)
            elif mode == 'Export':
                # Connect undo button to undo function
                button.pressed.connect(self.ExportToText)
            else:
                # Connect the button to setMode function
                button.pressed.connect(
                    lambda mode=mode: self.canvas.setMode(mode))
            # Add the buttun to layout widget
            palette.addWidget(button)

    # Delete all drawing
    def RefrshCanvas(self):
        # Paint all pixels back to black
        self.canvas.painter.fillRect(0, 0, self.canvas.width,
                                     self.canvas.height, QColor('#000000'))
        # Update canvas
        self.canvas.update()

    # Set mode to Scale and call function
    def Scale(self, mode):
        self.canvas.setMode('Scale')
        # Refresh the canvas from drawing
        self.RefrshCanvas()
        # Call Scale function
        self.TransformationImage.Scaling(self.canvas.painter, mode)
        # Update canvas
        self.canvas.update()

    # Set mode to Move and call function
    def Move(self, mode):
        self.canvas.setMode('Move')
        # Refresh the canvas from drawing
        self.RefrshCanvas()
        # Call Move function
        if mode == 'U': x, y = 0, -20
        elif mode == 'R': x, y = 20, 0
        elif mode == 'L': x, y = -20, 0
        elif mode == 'D': x, y = 0, 20
        self.TransformationImage.Move(self.canvas.painter, x, y)
        self.canvas.update()

    # Set mode to Rotate and call function
    def Rotate(self, mode):
        self.canvas.setMode('Rotate')
        # Refresh the canvas from drawing
        self.RefrshCanvas()
        # Call Rotate function
        if mode == 'L': r = -5
        elif mode == 'R': r = 5
        self.TransformationImage.Rotation(self.canvas.painter, r)
        self.canvas.update()

    # Set mode to Mirror and call function
    def Mirror(self):
        self.canvas.setMode('Mirror')
        # Refresh the canvas from drawing
        self.RefrshCanvas()
        # Call Mirror function
        self.TransformationImage.Mirroring(self.canvas.painter)
        self.canvas.update()

    # Set mode to Shearing and call function
    def Shearing(self):
        self.canvas.setMode('Shearing')

    def AddTransformationsButtons(self, palette):
        # For each transformation type make a button in this mode
        for mode in TRANS_MODES:
            button = ModesButton(mode)
            button.setFixedWidth(50)
            # Connect Draw button to FlipTransformationMode
            if mode == 'Draw':
                button.pressed.connect(self.FlipTransformationMode)
                # Connect scale button to scale function
            elif mode == "+":
                button.pressed.connect(lambda mode=mode: self.Scale('+'))
            elif mode == "-":
                button.pressed.connect(lambda mode=mode: self.Scale('-'))
                # Connect move button to move function
            elif mode == '↑':
                button.pressed.connect(lambda mode=mode: self.Move('U'))
            elif mode == '←':
                button.pressed.connect(lambda mode=mode: self.Move('L'))
            elif mode == '→':
                button.pressed.connect(lambda mode=mode: self.Move('R'))
            elif mode == '↓':
                button.pressed.connect(lambda mode=mode: self.Move('D'))

                # Connect rotate button to rotate function '⟲', '⟳'
            elif mode == '⟲':
                button.pressed.connect(lambda mode=mode: self.Rotate('L'))
            elif mode == '⟳':
                button.pressed.connect(lambda mode=mode: self.Rotate('R'))

                # Connect mirror button to mirror function
            elif mode == 'Mirror':
                button.pressed.connect(self.Mirror)
                button.setFixedWidth(100)

            # Connect mirror button to mirror function
            elif mode == 'Shearing':
                button.pressed.connect(self.Shearing)
                button.setFixedWidth(100)

            elif mode == 'Load':
                button.pressed.connect(self.LoadFromText)
                button.setFixedWidth(100)
            # Add the buttun to layout widget
            palette.addWidget(button)

    # Flip between draw mode and transformation mode
    def FlipTransformationMode(self):
        # Flip current transformation mode
        self.isTransformationMode = not self.isTransformationMode

        # If isTransformationMode == ture , replace to TransformationWidget
        if self.isTransformationMode:
            # Add current canvas
            self.TransformationLayout.addWidget(self.canvas)
            # Set mode to scale mode
            self.canvas.currentMode = TRANS_MODES[0]
            # Clean all but image
            self.RefrshCanvas()
            self.TransformationImage.DrawFromImage(
                self.canvas.painter, self.TransformationImage.currentImage)
            # Replace widget
            self.stackedWidget.setCurrentIndex(1)
        # Else replace to DrawWidget
        else:
            # Remove color layout
            self.DrawLayout.removeItem(self.colorPalette)
            # Add current canvas
            self.DrawLayout.addWidget(self.canvas)
            # Add new color layout
            self.colorPalette = QHBoxLayout()
            self.AddColorButtons(self.colorPalette)
            self.DrawLayout.addLayout(self.colorPalette)
            # Set mode to draw pixel
            self.canvas.currentMode = MODES[1]
            # Replace widget
            self.stackedWidget.setCurrentIndex(0)

    # Create top menue bar
    def CreateMenuBar(self):
        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu("File")
        # Creating save action
        saveAction = QAction("Save", self)
        # Setting save action shortcut
        saveAction.setShortcut(QKeySequence("Ctrl+S"))
        # Adding save action
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.SaveToImage)

        exportAction = QAction("Export ('txt')", self)
        # Setting export action shortcut
        exportAction.setShortcut(QKeySequence("Ctrl+E"))
        # Adding export action
        fileMenu.addAction(exportAction)
        exportAction.triggered.connect(self.ExportToText)

        loadAction = QAction("Load ('txt')", self)
        # Setting export action shortcut
        loadAction.setShortcut(QKeySequence("Ctrl+L"))
        # Adding export action
        fileMenu.addAction(loadAction)
        loadAction.triggered.connect(self.LoadFromText)

        clearAction = QAction("Clear", self)
        # Setting clear action shortcut
        clearAction.setShortcut(QKeySequence("Ctrl+C"))
        # Adding clear action
        fileMenu.addAction(clearAction)
        clearAction.triggered.connect(self.ClearCanvas)

    # Save the canvas as png
    def SaveToImage(self):
        # Select file to save to from file selection dialog
        filePath, _ = QFileDialog.getSaveFileName(
            self, "Save Image", "",
            "PNG(*.png);;JPEG(*.jpg *.jpeg);;All Files(*.*) ")
        if filePath == "":
            return
        # Get the pixmap from canvas
        pix = self.canvas.pixmap()
        # Make QImage from pixmap
        image = pix.toImage()
        # Save QImage as png
        image.save(filePath, 'png')

    # Export image to text file
    def ExportToText(self):
        # Open file selection dialog
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self, "QFileDialog.getOpenFileName()", "", options=options)
        # Make sure text file has selected. if not return
        if fileName.split('.')[-1] != 'txt':
            # Print error message
            self.ShowErrorMessage('Can\'t export to a none .txt file format')
            return
        # Open text file to write
        textFile = open(fileName, "w")
        # Init string
        actionString = ''
        # Save current transformation image to cuurentDraw
        self.TransformationImage.DrawFromImage(
            self.canvas.painter, self.TransformationImage.currentImage, True)
        # Create string
        for action in self.canvas.Draw.CurrentDraw:
            actionString += action
        # Remove last '\n' from string
        actionString = actionString[:-1]
        # Write string to selected file
        textFile.write(actionString)
        # Close selected file
        textFile.close()

    def LoadFromText(self):
        # Open file selection dialog
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self, "QFileDialog.getOpenFileName()", "", options=options)
        # Make sure text file has selected. if not return
        if fileName.split('.')[-1] != 'txt':
            # Print error message
            self.ShowErrorMessage('Please select an .txt file')
            return

        if not self.TransformationImage.DrawFromFile(self.canvas.painter,
                                                     fileName):
            self.ShowErrorMessage('Text file no in the rigth format')
        self.canvas.update()

    # Clear canvas drawing
    def ClearCanvas(self):
        # paint all pixels back to black
        self.canvas.painter.fillRect(0, 0, self.canvas.width,
                                     self.canvas.height, QColor('#000000'))
        # Delete actions array
        self.canvas.Draw.CurrentDraw = []
        # Delete current transfotmation image
        self.TransformationImage.currentImage = []
        self.TransformationImage.originImage = []
        # Update canvas
        self.canvas.update()

    # Popup error message
    def ShowErrorMessage(self, message):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        msg.setText(message)
        msg.setWindowTitle("Error")
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        retval = msg.exec_()
        msg.show()
コード例 #29
0
class SecondForm(QWidget):
    def __init__(self, creator):
        super().__init__()

        self.creator = creator
        self.mode = True

        self.setWindowTitle(
            f'Добавляем запись в {creator.comboBox.currentText()}')

        self.main_layout = QVBoxLayout(self)

        self.number_of_inputs = len(HEADERS[creator.comboBox.currentText()])
        self.hbox_layouts = []
        self.labels = []
        self.inputs = []

        self.add_change_bttn = QPushButton(self)
        self.add_change_bttn.setText('Добавить')
        self.add_change_bttn.clicked.connect(self.add_change)
        self.main_layout.addWidget(self.add_change_bttn)
        self.result = []

        self.setLayout(self.main_layout)

    # обработчик нажатия на клавиши "добавить и изменить"
    def add_change(self):
        con = sqlite3.connect('coefficients.sqlite')
        cur = con.cursor()
        table_name = self.creator.comboBox.currentText()
        self.number_of_inputs = len(
            HEADERS[self.creator.comboBox.currentText()])
        if self.mode:
            request = f'INSERT INTO {table_name} (' + \
                      ', '.join(HEADERS[table_name]) + \
                      ') VALUES ( ' + \
                      ', '.join([i.text() for i in self.inputs]) + \
                      ')'
            cur.execute(request).fetchall()
        else:
            request = f'UPDATE {table_name} SET ' + \
                      ', '.join([f'{HEADERS[table_name][i]} = {self.inputs[i].text()}'
                                 for i in range(1, self.number_of_inputs)]) + ' WHERE ' + \
                      f'id = {self.inputs[0].text()}' + ';'
            cur.execute(request).fetchall()

        con.commit()
        con.close()
        self.creator.update_table()
        self.close()

    # функция очистки формы
    def clear_form(self):
        for i in self.labels:
            i.deleteLater()
        self.labels = []
        for i in self.inputs:
            i.deleteLater()
        self.inputs = []
        for i in self.hbox_layouts:
            self.main_layout.removeItem(i)
            i.deleteLater()
        self.hbox_layouts = []

    # функция для построения формы в зависимости от изменяемой таблицы
    def add_widgets(self):
        self.number_of_inputs = len(
            HEADERS[self.creator.comboBox.currentText()])
        for i in range(self.number_of_inputs):
            self.hbox_layouts.append(QHBoxLayout(self))
            self.labels.append(QLabel(self))
            self.labels[-1].setText(
                HEADERS[self.creator.comboBox.currentText()][i])
            self.hbox_layouts[-1].addWidget(self.labels[-1])
            self.inputs.append(QLineEdit(self))
            self.hbox_layouts[-1].addWidget(self.inputs[-1])
            self.main_layout.addLayout(self.hbox_layouts[-1])
            if not self.mode:
                row = self.creator.tableWidget.currentRow()
                self.inputs[-1].setText(
                    self.creator.tableWidget.item(row, i).text())
                if i == 0:
                    self.inputs[-1].setEnabled(False)
        if self.mode:
            self.setWindowTitle(
                f'Добавляем запись в {self.creator.comboBox.currentText()}')
            self.add_change_bttn.setText('Добавить')
        else:
            self.setWindowTitle(
                f'Изменяем запись из {self.creator.comboBox.currentText()}')
            self.add_change_bttn.setText('Изменить')
コード例 #30
0
class Ui_MainWindow(object):
    widthSlot = 280

    def setupUi(self, MainWindow):
        self.MainWindow = MainWindow
        MainWindow.setObjectName("MainWindow")
        MainWindow.setFixedSize(315, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.calendarWidget = QtWidgets.QCalendarWidget(self.centralwidget)
        self.calendarWidget.setGeometry(QtCore.QRect(0, 370, 312, 183))
        self.calendarWidget.setObjectName("calendarWidget")

        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(0, 0, 321, 371))
        font = QtGui.QFont()
        font.setPointSize(6)
        self.tableWidget.setFont(font)
        #self.tableWidget.setAutoScroll(False)
        #self.tableWidget.setAutoScrollMargin(7)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(1)
        self.tableWidget.setRowCount(14)
        for i in range(self.tableWidget.rowCount()):
            item = QtWidgets.QTableWidgetItem()
            self.tableWidget.setVerticalHeaderItem(i, item)
        item = QtWidgets.QTableWidgetItem()
        item.setText("событие")
        self.tableWidget.setHorizontalHeaderItem(0, item)
        self.tableWidget.horizontalHeader().setDefaultSectionSize(280)
        self.tableWidget.horizontalHeader().setMinimumSectionSize(10)
        self.tableWidget.verticalHeader().setDefaultSectionSize(25)
        self.tableWidget.itemSelectionChanged.connect(self.show_form_add_event)


        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 319, 21))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.actionAddHand = QtWidgets.QAction(MainWindow)
        self.actionAddHand.setObjectName("actionAddHand")

        self.actionAddText = QtWidgets.QAction(MainWindow)
        self.actionAddText.setObjectName("actionAddText")
        self.actionAddHand.triggered.connect(self.show_form_add_event)

        self.action_3 = QtWidgets.QAction(MainWindow)
        self.action_3.setObjectName("action_3")
        self.menu.addAction(self.actionAddHand)
        self.menu.addAction(self.actionAddText)
        self.menu.addAction(self.action_3)
        self.menubar.addAction(self.menu.menuAction())

        # фрейм для отображения событий
        self.panelEvents = QVBoxLayout(self)
        self.panelEvents.setContentsMargins(0, 0, 0, 0)
        self.panelEvents

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        #Frame для событий втечении дня
        frame = Event_Frame(self, self.tableWidget)
        frame.setLayout(self.panelEvents)

        # # # ширина слота в одину минуту
        self.oneMinSlot = (325 - 66) / (10 * 60)

    def show_form_add_event(self):
        time = self.tableWidget.currentRow() + 9
        date = self.calendarWidget.selectedDate()
        print(date, time)
        #print(item)
        # передать дату и время
        self.form = form_add_event_UI.Ui_Dialog(date, time, self.calendar)
        self.form.show()

    def new_event(self, event):

        oneEventFrame = QFrame()
        heightSlot = event.duration * self.oneMinSlot
        #oneEventFrame.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed))
        #oneEventFrame.resize(Ui_MainWindow.widthSlot, heightSlot)
        oneEventFrame.setFixedHeight(heightSlot)
        oneEventFrame.setContentsMargins(0, 0, 0, 0)
        oneEventFrame.setStyleSheet("background-color: rgb(2, 116, 205); border-bottom: 1px solid rgb(128, 128, 255);")
        #color = QtGui.QColor(233, 10, 150)


        oneEventLayout = QHBoxLayout()
        oneEventLayout.setContentsMargins(0, 0, 0, 0)
        oneEventLayout.setObjectName("oneEventLayout")
        oneEventFrame.setLayout(oneEventLayout)
        oneEventLayout.setSpacing(0)

        labelNameEvent = QLabel()
        labelNameEvent.setToolTipDuration(10)
        labelNameEvent.setObjectName("labelNameEvent")
        #labelNameEvent.setText(event.time + " " + event.name)

        labelNameEvent.setAutoFillBackground(True)
        labelNameEvent.setFixedHeight(heightSlot)
        if event.link is not None:
            link = f'<a href="{event.link}">event.time + " " + event.name</a>'
        else:
            link = event.time + " " + event.name
        print(link)
        labelNameEvent.setText(link)
        labelNameEvent.setOpenExternalLinks(True)
        labelNameEvent.setStyleSheet("color: white;")
        sheet = "a { text-decoration: underline; color: white }"
        #labelNameEvent.setDefaultStyleSheet(sheet)
        #labelNameEvent.resize(Ui_MainWindow.widthSlot, oneEventFrame.height())
        oneEventLayout.addWidget(labelNameEvent)
        print(event.link)
        if event.link is not None:

            labelLinkImg = QLabel(link)
            labelLinkImg.setOpenExternalLinks(True)
            labelLinkImg.setMouseTracking(False)
            labelLinkImg.setLayoutDirection(QtCore.Qt.RightToLeft)
            labelLinkImg.setText("")
            labelLinkImg.setPixmap(QtGui.QPixmap("linkk.png"))
            labelLinkImg.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
            #self.label_img.setOpenExternalLinks(True)
            #self.label_img.setObjectName("label_img")
            oneEventLayout.addWidget(labelLinkImg)

        return oneEventFrame

    def clearLayoutEvent(self, eventLayout):
        frame_temp = eventLayout.widget().findChildren(type(QLabel()))
        print(f"Удалить событие {frame_temp[0].text()}")
        frame_temp[0].deleteLater()
        if len(frame_temp) > 1:
            frame_temp[1].deleteLater()
        eventLayout.widget().deleteLater()

    def clearPanelEvents(self):
        print(f"Удалить {self.panelEvents.count()} слотов")
        while self.panelEvents.count():
            child = self.panelEvents.takeAt(0)
            if isinstance(child, QtWidgets.QWidgetItem):
                self.clearLayoutEvent(child)
            self.panelEvents.removeItem(child)
            print(type(child))


    def add_events(self, events):

        self.clearPanelEvents()
        print(f"Добавить {len(events)} событий")
        if len(events) == 0:
            return
        #9:00 - это начало таблицы времен
        begin_event = schedule_class.Event("", "", time="09:00", duration=0)
        for i in range(len(events)):

            self.add_space_widget(begin_event, events[i])
            event_widget = self.new_event(events[i])
            self.panelEvents.addWidget(event_widget)

            begin_event = events[i]
        self.panelEvents.setSpacing(0)
        end_event = schedule_class.Event("", "", time="22:00", duration=0)
        self.add_space_widget(begin_event, end_event)


    def add_space_widget(self, begin_event, end_event):
        dt = schedule_class.Event.time_interval(begin_event, end_event)
        heightSlotSpace = int(dt * self.oneMinSlot)
        spacerItem = QSpacerItem(20, heightSlotSpace)
        self.panelEvents.addSpacerItem(spacerItem)
        #print(dt, "пустота = ",heightSlotSpace)


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Личный секретарь"))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("MainWindow", "время"))

        for i in range(1, self.tableWidget.rowCount()):
            item = self.tableWidget.verticalHeaderItem(i)
            item.setText(_translate("MainWindow", str(8+i)+":00"))

        self.menu.setTitle(_translate("MainWindow", "Добавить событие"))
        self.actionAddHand.setText(_translate("MainWindow", "Руками"))
        self.actionAddText.setText(_translate("MainWindow", "Из текста"))
        self.action_3.setText(_translate("MainWindow", "Из календаря"))