示例#1
0
    def _init_option_ui(self):
        label_start_time = QLabel("Start time: ")
        self._line_edit_start_time = QLineEdit()

        label_end_time = QLabel("End time: ")
        self._line_edit_end_time = QLineEdit()

        label_duration = QLabel("Duration: ")
        self._line_edit_duration = QLineEdit()

        label_num_clip = QLabel("No. of clips: ")
        self._line_edit_num_clip = QLineEdit()

        button_preview = QPushButton("Preview")
        button_preview.clicked.connect(self.button_preview_clicked)

        hbox = QHBoxLayout()
        hbox.addWidget(label_start_time)
        hbox.addWidget(self._line_edit_start_time)
        hbox.addWidget(label_end_time)
        hbox.addWidget(self._line_edit_end_time)
        hbox.addWidget(label_duration)
        hbox.addWidget(self._line_edit_duration)
        hbox.addWidget(label_num_clip)
        hbox.addWidget(self._line_edit_num_clip)
        hbox.addWidget(button_preview)

        for i in range(hbox.count() - 1):
            hbox.itemAt(i).widget().setObjectName("option")

        self.vbox.addLayout(hbox)
示例#2
0
class ShipSlot(QWidget):
    sloticon_table = None
    type_table = {1: 'MainCanonLight',
                  2: 'MainCanonMedium',
                  3: 'MainCanonHeavy',
                  4: 'SecondaryCanon',
                  5: 'Torpedo',
                  6: 'Fighter',
                  7: 'DiveBomber',
                  8: 'TorpedoBomber',
                  9: 'ReconPlane',
                  10:'ReconSeaplane',
                  11:'Rader',
                  12:'AAShell',
                  13:'APShell',
                  14:'DamageControl',
                  15:'AAGun',
                  16:'HighAngleGun',
                  17:'ASW',
                  18:'Soner',
                  19:'EngineImprovement',
                  20:'LandingCraft',
                  21:'Autogyro',
                  22:'ArtillerySpotter',
                  23:'AntiTorpedoBulge',
                  24:'SearchLight',
                  25:'DrumCanister',
                  26:'Facility',
                  27:'Flare',
                  28:'FleetCommandFacility',
                  29:'MaintenancePersonnel',
                  30:'AntiAircraftFireDirector',
                  31:'RocketLauncher',
                  32:'SurfaceShipPersonnel',
                  33:'FlyingBoat'
    }

    def __init__(self,parent):
        super(ShipSlot, self).__init__(parent)

        if self.sloticon_table is None:
            self.sloticon_table = slotitem.create_sloticontable()

        self.box = QHBoxLayout()
        self.box.setSpacing(3)
        self.box.setContentsMargins(0,5,0,5)

        self.setLayout(self.box)

    def set_slot(self, types):
        # remove all icon
        for i in reversed(list(range(self.box.count()))):
            self.box.itemAt(i).widget().setParent(None)

        for t in types:
            type_name = self.type_table.get(t, 'unknown')
            if not type_name in self.sloticon_table:
                type_name = 'unknown'
            self.box.addWidget(slotitem.IconBox(self.sloticon_table[type_name]))
示例#3
0
    def _init_browse_ui(self):
        label_file_name = QLabel("File name: ")

        self._list_widget_file_names = QListWidget()
        self._list_widget_file_names.setFixedHeight(100)

        button_browse = QPushButton("Browse")
        button_browse.clicked.connect(self.button_browse_clicked)
        button_add = QPushButton("Add")
        button_add.clicked.connect(self.button_add_clicked)
        button_remove = QPushButton("Remove")
        button_remove.clicked.connect(self.button_remove_clicked)

        vbox = QVBoxLayout()
        vbox.addWidget(button_browse)
        vbox.addWidget(button_add)
        vbox.addWidget(button_remove)

        hbox = QHBoxLayout()
        hbox.addWidget(label_file_name)
        hbox.addWidget(self._list_widget_file_names)
        hbox.addLayout(vbox)

        for i in range(hbox.count()):
            hbox.setAlignment(hbox.itemAt(i).widget(), Qt.AlignTop)

        self.vbox.addLayout(hbox)
示例#4
0
class MenuBar(QTabWidget):
    def __init__(self, parent=None):
        super(MenuBar, self).__init__(parent)

        tabbar = TabBar(parent)
        self.setTabBar(tabbar)
        self.setMinimumHeight(135)
        self.setMouseTracking(True)

        self._drop = False
        self.currentChanged.connect(self.currentChangedFunc)

    def currentChangedFunc(self, index):
        tab_text = self.tabText(index)
        menu = self.findChild(MenuWidget, tab_text)
        self.anim = QPropertyAnimation(menu, b'_height')
        self.anim.setDuration(100)
        self.anim.setStartValue(0)
        self.anim.setEndValue(100)
        self.anim.start()

    def addMenu(self, p_str):
        p_str = "  {p_str}  ".format(p_str=p_str)
        menu = MenuWidget()
        menu.setObjectName(p_str)
        self.addTab(menu, p_str)
        self.hlayout = QHBoxLayout(menu)
        self.hlayout.setObjectName(p_str)
        self.hlayout.setContentsMargins(0, 0, 0, 0)
        self.hlayout.setSpacing(0)
        hs = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.hlayout.addItem(hs)
        return (menu)

    def addGroup(self, p_str, menu):
        group = GroupWidget(p_str, menu)
        group.setObjectName('group')
        insert_index = len(menu.findChildren(GroupWidget, 'group')) - 1
        self.hlayout.insertWidget(insert_index, group)
        return (group)

    def listGroups(self, menu):
        self.group_list = []
        for i in range(self.hlayout.count()):
            try:
                w = self.hlayout.itemAt(i).widget()
                self.group_list.append(w._title)
            except:
                AttributeError
        return (self.group_list)

    def addSliderChoiceWidget(self, menu):
        slider_choice = SliderChoiceWidget()
        insert_index = len(menu.findChildren(GroupWidget, 'group'))
        self.hlayout.insertWidget(insert_index, slider_choice)
        return (slider_choice)
示例#5
0
class ThumbnailRow(QWidget):

    def __init__(self):
        super().__init__()
        self.labels = []
        self.layout = QHBoxLayout()
        self.layout.setSpacing(3)
        self.layout.setContentsMargins(3, 0, 0, 3)
        self.setLayout(self.layout)
        self.items = []

    def add_items(self, items):
        self.items = items
        self.draw_items()

    def draw_items(self):
        self.clear()
        for item in self.items:
            thumbnail = Thumbnail(item)
            self.layout.addWidget(thumbnail, 0)
        self.layout.addWidget(QWidget(), 1)

    def clear(self):
        for i in reversed(range(self.layout.count())):
            widget = self.layout.itemAt(i).widget()
            # remove it from the layout list
            self.layout.removeWidget(widget)
            # remove it from the gui
            widget.setParent(None)

    def zoom(self, scale):
        for i in reversed(range(self.layout.count())):
            widget = self.layout.itemAt(i).widget()
            if isinstance(widget, Thumbnail):
                widget.zoom(scale)

    def mousePressEvent(self, a0: QtGui.QMouseEvent):
        print("Mouse Press")

    def mouseDoubleClickEvent(self, a0: QtGui.QMouseEvent):
        print("Mouse Double Click")
示例#6
0
    def _init_info_ui(self):
        self._text_edit = QTextEdit()
        self._text_edit.setFixedHeight(80)
        self._text_edit.setReadOnly(True)
        button_create = QPushButton("Create")
        button_create.clicked.connect(self.button_create_clicked)
        button_upload = QPushButton("Upload")
        button_upload.clicked.connect(self.button_upload_clicked)

        vbox = QVBoxLayout()
        vbox.addWidget(button_create)
        vbox.addWidget(button_upload)

        hbox = QHBoxLayout()
        hbox.addWidget(self._text_edit)
        hbox.addLayout(vbox)

        for i in range(hbox.count()):
            hbox.setAlignment(hbox.itemAt(i).widget(), Qt.AlignTop)

        self.vbox.addLayout(hbox)
示例#7
0
class HorizontalImageScrollArea(QScrollArea):
    def __init__(self, parent=None):
        super(HorizontalImageScrollArea, self).__init__(parent)
        self.setWidgetResizable(True)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setFrameShape(QFrame.NoFrame)

        self.layout = QHBoxLayout()

        scroll = QWidget()
        scroll.setLayout(self.layout)
        self.setWidget(scroll)

    def eventFilter(self, obj, event):
        if obj == self.widget() and event.type() == QEvent.Resize:
            self.widget().resize(self.calcNewSize())
            return True

        return super(HorizontalImageScrollArea, self).eventFilter(obj, event)

    def calcNewSize(self):
        height = self.viewport().height()

        layoutMargins = self.layout.contentsMargins()
        heightForCalc = height - layoutMargins.top() - layoutMargins.bottom()

        width = self.calcWidthForHeight(heightForCalc)
        return QSize(width, height)

    def calcWidthForHeight(self, height):
        width = 0
        for wgt in range(self.layout.count()):
            width += self.layout.itemAt(wgt).widget().widthForHeight(height)

        if self.layout.count() > 1:
            width += self.layout.spacing() * (self.layout.count() - 1)
        return width
示例#8
0
class Widgetboard(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()
        # イベントループ

    def initUI(self):
        self.resize(400, 400)  # 横, 縦
        # self.move(300, 300)
        self.setWindowTitle('sample')
        self.mainlayout = QHBoxLayout()
        self.mode = "board"
        # 画面左側のレイアウト
        self.rightlayout = QVBoxLayout()
        self.setallcard()
        # 画面右側のレイアウト
        self.leftlayout = QVBoxLayout()
        # ボードに関するレイアウト
        self.boardlayout = QHBoxLayout()
        self.boardtoplayout = QHBoxLayout()
        self.boardtitle = QLabel("board")
        self.boardsetbutton = QPushButton("setboard")
        self.boardsetbutton.clicked.connect(self.setmode)
        self.boardclearbutton = QPushButton("clearboard")
        self.boardclearbutton.clicked.connect(self.clearmethod)
        self.boardtoplayout.addWidget(self.boardtitle)
        self.boardtoplayout.addWidget(self.boardsetbutton)
        self.boardtoplayout.addWidget(self.boardclearbutton)
        # ホールカードの関するレイアウト
        self.holllayout = QHBoxLayout()
        self.holltoplayout = QHBoxLayout()
        self.holltitle = QLabel("hollcard")
        self.hollsetbutton = QPushButton("sethollcard")
        self.hollsetbutton.clicked.connect(self.setmode)
        self.hollclearbutton = QPushButton("clearhollcard")
        self.hollclearbutton.clicked.connect(self.clearmethod)
        self.holltoplayout.addWidget(self.holltitle)
        self.holltoplayout.addWidget(self.hollsetbutton)
        self.holltoplayout.addWidget(self.hollclearbutton)
        # 全体レイアウト
        self.leftlayout.addLayout(self.boardtoplayout)
        self.leftlayout.addLayout(self.boardlayout)
        self.leftlayout.addLayout(self.holltoplayout)
        self.leftlayout.addLayout(self.holllayout)
        self.boardcardlist = []
        self.hollcardlist = []
        # メインのレイアウトを作る
        self.mainlayout.addLayout(self.rightlayout)
        self.mainlayout.addLayout(self.leftlayout)
        self.setLayout(self.mainlayout)
        self.show()

    def setallcard(self):
        rank = [
            "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"
        ]
        suit = ["s", "h", "d", "c"]
        for r in rank:
            layout = QHBoxLayout()
            for s in suit:
                exec(f"self.button{r}{s} = QPushButton('{r}{s}')")
                exec(f"self.button{r}{s}.setIcon(QIcon('./PNG/{r}{s}.png'))")
                exec(f"self.button{r}{s}.setIconSize(QSize(40, 40))")
                exec(f"self.button{r}{s}.clicked.connect(self.button_clicked)")
                exec(f"layout.addWidget(self.button{r}{s})")
            self.rightlayout.addLayout(layout)

    def button_clicked(self):
        sender = self.sender()
        text = sender.text()
        if self.mode == "board":
            if len(self.boardcardlist) < 5:
                self.boardcardlist.append(text)
                self.addcard(text)
        elif self.mode == "hollcard":
            if len(self.hollcardlist) < 2:
                self.hollcardlist.append(text)
                self.addcard(text)
        # print(f"board: {self.boardcardlist}")
        # print(f"hollcard: {self.hollcardlist}")

    def setmode(self):
        sender = self.sender()
        text = sender.text()
        if text == "setboard":
            self.mode = "board"
        elif text == "sethollcard":
            self.mode = "hollcard"

    def addcard(self, text):
        pixmap = QPixmap(f'./PNG/{text}.png').scaled(QSize(150, 150),
                                                     Qt.KeepAspectRatio,
                                                     Qt.FastTransformation)
        imagelabel = QLabel()
        imagelabel.setPixmap(pixmap)
        if self.mode == "board":
            self.boardlayout.addWidget(imagelabel)
        elif self.mode == "hollcard":
            self.holllayout.addWidget(imagelabel)

    def clearmethod(self):
        sender = self.sender()
        text = sender.text()
        if text == "clearboard":
            self.boardcardlist = []
            for i in reversed(range(self.boardlayout.count())):
                self.boardlayout.itemAt(i).widget().setParent(None)
        elif text == "clearhollcard":
            self.hollcardlist = []
            for i in reversed(range(self.holllayout.count())):
                self.holllayout.itemAt(i).widget().setParent(None)
        else:
            pass
示例#9
0
文件: E-Mapp.py 项目: MERTULAS/E-Mapp
class Window(QWidget):
    def __init__(self, login_id, login_password):
        super().__init__()
        self.id = login_id
        self.password = login_password
        self.inbox = ""
        self.init_ui()

    def inbox_mails(self, mail):
        self.incoming_mail = QGroupBox()
        self.incoming_mail_group = QVBoxLayout(self.incoming_mail)
        self.inbox_subject = QLabel("Subject: " + mail[0])
        self.inbox_from = QLabel("From: " + mail[1])
        self.incoming_mail_group.addWidget(self.inbox_subject)
        self.incoming_mail_group.addWidget(self.inbox_from)
        self.box_palette = QPalette()
        self.box_palette.setColor(QPalette.Background, QColor(100, 100, 100))
        self.setPalette(self.box_palette)
        return self.incoming_mail

    def inbox_container(self):
        self.scrollArea = QScrollArea(self)
        self.scrollArea.setMaximumWidth(250)
        self.scrollArea.setMinimumWidth(100)
        self.scrollArea.setWidgetResizable(True)
        self.widget = QWidget()
        self.scrollArea.setWidget(self.widget)
        self.layoutScrollArea = QVBoxLayout()
        self.inbox = MailSettings.inbox_getter(self.id, self.password)
        for index, mail_in_inbox in enumerate(self.inbox):
            self.layoutScrollArea.addWidget(self.inbox_mails(mail_in_inbox))
        self.widget.setLayout(self.layoutScrollArea)

    def init_ui(self):
        self.mail_address = QLineEdit()
        self.send_button = QPushButton("Send!")
        self.mail_text = QTextEdit()
        self.mail_subject = QLineEdit()
        self.label_to = QLabel("To:")
        self.label_subject = QLabel("Subject:")
        self.label_text = QLabel("Text:")
        self.label_text.setFixedWidth(50)
        self.attached_file_paths = []
        self.warning_label = QLabel("")
        self.warning_label_head = QLabel("")
        self.hidden_inbox_button = QPushButton("<", self)
        self.hidden_inbox_button.setFixedSize(30, 70)
        self.file_open_button = QPushButton("Attach")
        self.file_open_button.setIcon(QIcon('attach-paperclip-symbol.png'))
        self.delete_all_files = QPushButton("Delete All")
        self.delete_all_files.hide()

        self.delete_all_files.clicked.connect(self.del_all_files)
        self.hidden_inbox_button.clicked.connect(self.hidden_inbox)
        self.file_open_button.clicked.connect(self.file_open)

        v_box1 = QVBoxLayout()
        v_box1.addWidget(self.label_to)
        v_box1.addWidget(self.label_subject)

        v_box2 = QVBoxLayout()
        v_box2.addWidget(self.mail_address)
        v_box2.addWidget(self.mail_subject)

        h_box1 = QHBoxLayout()
        h_box1.addLayout(v_box1)
        h_box1.addLayout(v_box2)

        h_box2 = QHBoxLayout()
        h_box2.addWidget(self.label_text)
        h_box2.addWidget(self.mail_text)

        v_box_attach = QVBoxLayout()
        v_box_attach.addWidget(self.file_open_button)

        self.h_box_files = QHBoxLayout()

        h_box3 = QHBoxLayout()
        h_box3.addLayout(self.h_box_files)
        h_box3.addStretch()
        h_box3.addWidget(self.delete_all_files)
        h_box3.addWidget(self.file_open_button)

        self.v_box = QVBoxLayout()
        self.v_box.addLayout(h_box1)
        self.v_box.addLayout(h_box2)
        self.v_box.addLayout(h_box3)
        self.v_box.addWidget(self.warning_label_head)
        self.v_box.addWidget(self.warning_label)
        self.v_box.addWidget(self.send_button, 10)

        self.inbox_container()
        h_box4 = QHBoxLayout()
        h_box4.addWidget(self.scrollArea)
        h_box4.addWidget(self.hidden_inbox_button)

        h_box5 = QHBoxLayout()
        h_box5.addLayout(h_box4)
        h_box5.addLayout(self.v_box)
        self.setLayout(h_box5)
        self.send_button.clicked.connect(self.send)

    def send(self):
        to = self.mail_address.text()
        subject = self.mail_subject.text()
        text = self.mail_text.toPlainText()
        file = self.attached_file_paths
        mail = MailSettings(to, subject, text, file, self.id, self.password)
        warnings = mail.mail_sender()
        if warnings:
            warning = "\n".join(warnings)
            self.warning_label_head.setText("Invalid e-mail addresses:\n")
            self.warning_label_head.setStyleSheet(
                "color: red; border: 2px solid red; border-radius: 5px")
            self.warning_label.setText(warning)

    def hidden_inbox(self):
        if self.scrollArea.isHidden():
            self.scrollArea.show()
            self.hidden_inbox_button.setText("<")
            self.setGeometry(self.x() + 1,
                             self.y() + 1,
                             self.width() + 1,
                             self.height() + 1)
            self.update()
        else:
            self.scrollArea.hide()
            self.hidden_inbox_button.setText(">")
            self.setGeometry(self.x() + 1,
                             self.y() + 1,
                             self.width() + 1,
                             self.height() + 1)
            self.update()

    def file_open(self):
        file_name = QFileDialog.getOpenFileName(self, "Select File",
                                                os.getenv("HOME"))
        if file_name[0] not in self.attached_file_paths and file_name[0] != "":
            self.attached_file_paths.append(str(file_name[0]))
            self.h_box_files.addWidget(
                QLabel("{}-)".format(len(self.attached_file_paths)) +
                       file_name[0].split("/")[-1] + " "))
            # print(self.attached_file_paths)
            self.delete_all_files.show()
        else:
            pass

    def del_all_files(self):
        self.attached_file_paths = []
        self.delete_all_files.hide()
        for i in reversed(range(self.h_box_files.count())):
            self.h_box_files.itemAt(i).widget().setParent(None)
        self.setGeometry(self.x() + 1,
                         self.y() + 1,
                         self.width() + 1,
                         self.height() + 1)
        self.update()
示例#10
0
文件: gui.py 项目: Gareth001/500
class Controller(QWidget):
    def __init__(self):
        super().__init__()

        # game details
        self._player = 0
        self._players = None
        self._round = None
        self._cards_played = 0

        # child processes
        self._server = None
        self._client = None
        self._parent_conn = None  # connection to child

        # set graphics properties
        self.setWindowTitle('500')
        self.setGeometry(50, 50, WIDTH, HEIGHT)
        self.setFixedSize(self.size())

        # check for background image
        if os.path.exists("bkg.jpg"):
            bg = QtGui.QPixmap("bkg.jpg")
            palette = QtGui.QPalette()
            palette.setBrush(10, QtGui.QBrush(bg))
            self.setPalette(palette)

        else:
            print(
                "No background image found. Copy bkg.jpg to the directory to add one."
            )

        # default font
        self.setFont(QtGui.QFont("Book Antiqua", 11, QtGui.QFont.Bold))

        # create main menu
        self._main_menu = QWidget()
        self.create_main_menu_view()

        # create game options view
        self._options_type = None  # which options screen to display
        self._port = None
        self._username = None
        self._ip = None
        self._password = None
        self._player_types = [None] * 3
        self._game_options_view = QWidget()
        self.create_game_options_view()

        # create game view
        self._game_view = QWidget()
        self._card_layout = [None] * NUMBER_PLAYERS  # array of players cards
        self._played_cards = None  # four cards in center of screen
        self._player_info = [None
                             ] * NUMBER_PLAYERS  # info label for each player
        self._bet_controls = []
        self._card_winning = None
        self.create_game_view()

        # create stacked layout
        self._stacked_layout = QStackedWidget(self)
        self._stacked_layout.addWidget(self._main_menu)
        self._stacked_layout.addWidget(self._game_options_view)
        self._stacked_layout.addWidget(self._game_view)

        self.show()

    # create main menu and add it to _main_menu layout
    def create_main_menu_view(self):

        menu = QVBoxLayout()
        menu.setAlignment(QtCore.Qt.AlignHCenter)
        menu.addStretch(1)

        # create a pretty title layout
        title_layout = QHBoxLayout()
        title_layout.addStretch(1)

        # add some bowers for nice looks
        svgWidget = QtSvg.QSvgWidget('img/JH.svg')
        svgWidget.setMinimumHeight(CARD_HEIGHT)
        svgWidget.setMaximumHeight(CARD_HEIGHT)
        svgWidget.setMinimumWidth(CARD_WIDTH)
        svgWidget.setMaximumWidth(CARD_WIDTH)
        title_layout.addWidget(svgWidget)
        title_layout.addStretch(1)

        # create title
        title = QLabel("500 Online!")
        font = QtGui.QFont("Book Antiqua", 50, QtGui.QFont.Bold)
        title.setFont(font)
        title_layout.addWidget(title)
        title_layout.addStretch(1)

        svgWidget = QtSvg.QSvgWidget('img/JD.svg')
        svgWidget.setMinimumHeight(CARD_HEIGHT)
        svgWidget.setMaximumHeight(CARD_HEIGHT)
        svgWidget.setMinimumWidth(CARD_WIDTH)
        svgWidget.setMaximumWidth(CARD_WIDTH)
        title_layout.addWidget(svgWidget)

        title_layout.addStretch(1)
        menu.addLayout(title_layout)
        menu.addStretch(1)

        # create layout
        layout = QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignCenter)

        # bots button
        button = QPushButton('Play against bots', self)
        button.clicked.connect(lambda: self.goto_game_options(0))
        layout.addWidget(button)

        # join server
        button = QPushButton('Join a server', self)
        button.clicked.connect(lambda: self.goto_game_options(1))
        layout.addWidget(button)

        # host and play
        button = QPushButton('Host and play', self)
        button.clicked.connect(lambda: self.goto_game_options(2))
        layout.addWidget(button)

        # options TODO
        # button = QPushButton('Options', self)
        # layout.addWidget(button)

        # exit
        button = QPushButton('Exit', self)
        button.clicked.connect(self.close)
        layout.addWidget(button)

        menu.addLayout(layout)
        menu.addStretch(2)

        # title = QLabel("By Gareth Booth") TODO
        # font = QtGui.QFont("Book Antiqua", 8, QtGui.QFont.Bold)
        # title.setFont(font)
        # menu.addWidget(title)

        # add to layout
        self._main_menu.setLayout(menu)

    # go to the game options screen
    # type is which screen button you came from:
    # 0 for bots
    # 1 for join server
    # 2 for host and play
    def goto_game_options(self, options_type):
        self._options_type = options_type
        self._stacked_layout.setCurrentIndex(1)
        self.reset_game_options()

        # hide layouts depending on which options type we are
        if options_type == 0:
            self._ip.hide()
            self._password.hide()
            for index in range(0, 3):
                self._player_types[index].hide()

        elif options_type == 1:
            for index in range(0, 3):
                self._player_types[index].hide()

        elif options_type == 2:
            self._ip.hide()

    # unhide all game options (note port and username are never hidden)
    def reset_game_options(self):
        self._ip.show()
        self._password.show()
        for index in range(0, 3):
            self._player_types[index].show()

    # create the options for joining game menu
    def create_game_options_view(self):
        # create layout
        layout = QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignCenter)

        # username
        edit = QLineEdit()
        edit.setText("Jimmy")
        edit.setMaximumWidth(200)
        self._username = QWidget()
        self._username.setLayout(create_menu_entry("Username: "******"Port: ", port))
        layout.addWidget(self._port)

        # ip
        ip = QLineEdit()
        ip.setMaximumWidth(200)
        self._ip = QWidget()
        self._ip.setLayout(create_menu_entry("Ip Address: ", ip))
        layout.addWidget(self._ip)

        # password
        password = QLineEdit()
        password.setMaximumWidth(200)
        self._password = QWidget()
        self._password.setLayout(create_menu_entry("Password: "******"Human", "lvl 1 bot", "lvl 2 bot"])
            player_type.setMaximumWidth(200)
            self._player_types[index] = QWidget()
            self._player_types[index].setLayout(
                create_menu_entry("Player " + str(index + 2) + " is a :",
                                  player_type))
            layout.addWidget(self._player_types[index])

        # join button
        button = QPushButton('Go', self)
        button.clicked.connect(self.create_game)
        layout.addWidget(button)

        # back button
        button = QPushButton('Back to Menu', self)
        button.clicked.connect(lambda: self._stacked_layout.setCurrentIndex(0))
        layout.addWidget(button)

        # create layout with stretch to force center the controls
        hcentered_layout = QHBoxLayout()
        hcentered_layout.addStretch(1)
        hcentered_layout.addLayout(layout)
        hcentered_layout.addStretch(1)

        self._game_options_view.setLayout(hcentered_layout)

    # returns username from the game options screen
    def get_username(self):
        return self._username.layout().itemAt(1).widget().text()

    # returns port from the game options screen
    def get_port(self):
        return self._port.layout().itemAt(1).widget().value()

    # returns password from the game options screen
    def get_password(self):
        return self._password.layout().itemAt(1).widget().text()

    # returns password from the game options screen
    def get_ip(self):
        return self._ip.layout().itemAt(1).widget().text()

    # returns player type from the game options screen for given player
    def get_player_type(self, index):
        return self._player_types[index].layout().itemAt(
            1).widget().currentIndex()

    # creates game view and adds it to _game_view layout
    def create_game_view(self):
        # layout
        game_layout = QVBoxLayout()

        self._card_layout[2] = QHBoxLayout()
        # create card iamges for teammate
        for _ in range(0, 10):
            svgWidget = QtSvg.QSvgWidget('img/BACK.svg')
            svgWidget.setFixedSize(CARD_WIDTH, CARD_HEIGHT)
            self._card_layout[2].addWidget(svgWidget)

        # add this card layout
        game_layout.addLayout(self._card_layout[2])

        # Hbox for center of the screen
        middle_layout = QHBoxLayout()

        # player on other team
        self._card_layout[1] = QVBoxLayout()
        self._card_layout[1].setAlignment(QtCore.Qt.AlignLeft)

        for _ in range(0, 10):
            svgWidget = QtSvg.QSvgWidget('img/BACK.svg')
            svgWidget.setFixedSize(CARD_WIDTH / 2, CARD_HEIGHT / 2)
            self._card_layout[1].addWidget(svgWidget)

        # add this card layout
        middle_layout.addLayout(self._card_layout[1])

        # add other team info label
        self._player_info[1] = QLabel(self)
        self._player_info[1].setAlignment(QtCore.Qt.AlignLeft
                                          | QtCore.Qt.AlignVCenter)
        middle_layout.addWidget(self._player_info[1])

        # layout in middle center (for teammate and your info)
        middle_center_layout = QVBoxLayout()

        # add teammate info label
        self._player_info[2] = QLabel(self)
        self._player_info[2].setAlignment(QtCore.Qt.AlignTop
                                          | QtCore.Qt.AlignHCenter)
        middle_center_layout.addWidget(self._player_info[2])

        middle_center_layout.addStretch(1)

        # add where the 4 cards will go during play
        self._played_cards = QHBoxLayout()
        for _ in range(0, NUMBER_PLAYERS):

            # layout containing this tricks details
            sublayout = QVBoxLayout()
            sublayout.setAlignment(QtCore.Qt.AlignVCenter)

            # text
            top_text = QLabel()
            sublayout.addWidget(top_text)

            # card image
            svgWidget = QtSvg.QSvgWidget('img/BACK.svg')
            svgWidget.setFixedSize(CARD_WIDTH, CARD_HEIGHT)
            sublayout.addWidget(svgWidget)

            # text
            bottom_text = QLabel()
            sublayout.addWidget(bottom_text)

            self._played_cards.addLayout(sublayout)

        # add this card layout
        middle_center_layout.addLayout(self._played_cards)

        middle_center_layout.addStretch(1)

        # add player info label
        self._player_info[0] = QLabel(self)
        self._player_info[0].setAlignment(QtCore.Qt.AlignBottom
                                          | QtCore.Qt.AlignCenter)
        middle_center_layout.addWidget(self._player_info[0])

        # add middle center layout to middle layout
        middle_layout.addLayout(middle_center_layout)

        # add other team info label
        self._player_info[3] = QLabel(self)
        self._player_info[3].setAlignment(QtCore.Qt.AlignRight
                                          | QtCore.Qt.AlignVCenter)
        middle_layout.addWidget(self._player_info[3])

        # set player info as waiting
        for index in range(0, 4):
            self._player_info[index].setText("Waiting for player")

        self._card_layout[3] = QVBoxLayout()
        self._card_layout[3].setAlignment(QtCore.Qt.AlignRight)
        # create card iamges for other team
        for _ in range(0, 10):
            svgWidget = QtSvg.QSvgWidget('img/BACK.svg')
            svgWidget.setFixedSize(CARD_WIDTH / 2, CARD_HEIGHT / 2)
            self._card_layout[3].addWidget(svgWidget)

        # add this card layout
        middle_layout.addLayout(self._card_layout[3])

        # add the middle layout
        game_layout.addLayout(middle_layout)

        # create card iamges for player
        self._card_layout[0] = QHBoxLayout()
        self._card_layout[0].setAlignment(QtCore.Qt.AlignBottom)
        for index in range(0, 13):
            svgWidget = QtSvg.QSvgWidget('img/BACK.svg')
            svgWidget.setFixedSize(CARD_WIDTH, CARD_HEIGHT)

            if index >= 10:
                svgWidget.hide()

            self._card_layout[0].addWidget(svgWidget)

        # add this card layout
        game_layout.addLayout(self._card_layout[0])

        # add to layout
        game_layout.addLayout(self.create_bet_controls())
        self._game_view.setLayout(game_layout)

    # returns layout containing all bet controls
    def create_bet_controls(self):
        # create layout for betting actions
        layout = QHBoxLayout()

        # number bet choice button
        number_bet = QComboBox()
        number_bet.addItems(["6", "7", "8", "9", "10"])
        layout.addWidget(number_bet)
        self._bet_controls.append(number_bet)

        # suit bet choice button
        suit_bet = QComboBox()
        suit_bet.addItems(
            ["Spades", "Clubs", "Diamonds", "Hearts", "No Trumps"])
        layout.addWidget(suit_bet)
        self._bet_controls.append(suit_bet)

        # bet button, sends bet based on what we entered in the choice boxes above
        button = QPushButton('Bet', self)
        button.clicked.connect(lambda: self.send_to_client(
            number_bet.currentText() + suit_to_letter(suit_bet.currentText())))
        layout.addWidget(button)
        self._bet_controls.append(button)

        # pass button
        button = QPushButton('Pass', self)
        button.clicked.connect(lambda: self.send_to_client("PASS"))
        layout.addWidget(button)
        self._bet_controls.append(button)

        # misere button
        button = QPushButton('Bet Misere', self)
        button.clicked.connect(lambda: self.send_to_client("MISERE"))
        layout.addWidget(button)
        self._bet_controls.append(button)

        # open misere button (TODO functionality, such as seeing persons hand)
        button = QPushButton('Bet Open Misere', self)
        button.clicked.connect(lambda: self.send_to_client("OPENMISERE"))
        layout.addWidget(button)
        self._bet_controls.append(button)

        layout.addStretch(1)

        # main menu button
        button = QPushButton('Exit to menu', self)
        layout.addWidget(button)
        button.clicked.connect(lambda: self.exit_to_menu())
        self._bet_controls.append(button)

        # disable bet buttons by default
        self.activate_bet_controls(set=False)

        return layout

    # toggles button activation
    # leave bool as None to toggle bet
    def activate_bet_controls(self, set=None):
        for elem in self._bet_controls[:len(self._bet_controls) - 1]:
            elem.setEnabled(not elem.isEnabled() if set == None else set)

    # reset bet controls
    def reset_bet_controls(self):
        self.activate_bet_controls(set=False)
        self._bet_controls[0].setCurrentIndex(0)
        self._bet_controls[1].setCurrentIndex(0)

    # given deck, updates the players hand
    def update_player_hand(self, deck, setEvent=False):
        # update each card
        for i, card in enumerate(deck):
            widget = self._card_layout[self._player].itemAt(i).widget()
            widget.load('img/' + card + '.svg')

            # show kitty cards if we are in kitty round
            if i >= 10:
                widget.show()

            # we only need this set after it is possible to choose a card
            if setEvent:
                # note the extra card=card argument to stop each
                # lambda using local variable card

                # if we are in the kitty round, you can't
                # choose an invalid card, so remove it instantly
                widget.mouseReleaseEvent = (
                    lambda event, card=card: self.send_card(
                        card, remove=bool(len(deck) > 10)))

    # resets all players hands
    def reset_players_hands(self):
        # show each players cards again
        for i in range(0, NUMBER_PLAYERS):
            for j in range(0, 10):
                widget = self._card_layout[i].itemAt(j).widget()
                widget.load('img/BACK.svg')
                widget.show()

        # hide kitty cards again
        for i in range(10, 13):
            self._card_layout[self._player].itemAt(i).widget().hide()

        # reset card layout to what it was before
        self.rearrange_card_layout(
            -int(self._player))  # int to remove pylint errors

    # show the players first 10 cards and hide the last 3
    def reset_player_hand_after_kitty(self):
        for i in range(0, 10):
            self._card_layout[self._player].itemAt(i).widget().show()
        for i in range(10, 13):
            self._card_layout[self._player].itemAt(i).widget().hide()

    # sends card to client, optionally remove them
    def send_card(self, card, remove=False):
        self.send_to_client(card)

        if remove == True:
            self.remove_card_from_hand(self._player, card)

    # toggles card controls
    # supply set to give them a value
    def activate_card_controls(self, set=None):

        for i in range(0, self._card_layout[self._player].count()):
            widget = self._card_layout[self._player].itemAt(i).widget()
            widget.setEnabled(not widget.isEnabled() if set == None else set)

    # removes given card from our hand
    # note closing the widget does not decrease the count of cards in the layout
    def remove_card_from_hand(self, player, card):

        # find location of card in our deck and close that widget
        if player == self._player:
            index = self._players[self._player]["deck"].index(card)
        else:
            index = self._round
        self._card_layout[player].itemAt(index).widget().hide()

    # resets the cards played interface
    def reset_cards_played(self):
        self._cards_played = 0

        # reset image and text
        for i in range(0, self._played_cards.count()):
            self._played_cards.itemAt(i).layout().itemAt(0).widget().setText(
                "")
            self._played_cards.itemAt(i).layout().itemAt(1).widget().load(
                'img/BACK.svg')

        self.reset_card_winning()

    # reset the winning text
    def reset_card_winning(self):
        for i in range(0, self._played_cards.count()):
            self._played_cards.itemAt(i).layout().itemAt(2).widget().setText(
                "")

    # adds the card to the center
    def add_card_played(self, card, player, winning):
        self._played_cards.itemAt(self._cards_played).layout().\
                itemAt(0).widget().setText("Player " + str(player + 1))
        self._played_cards.itemAt(self._cards_played).layout().\
                itemAt(1).widget().load('img/' + card + '.svg')

        # update winning text
        if winning:
            self.reset_card_winning()
            self._played_cards.itemAt(self._cards_played).layout().\
                    itemAt(2).widget().setText("WINNING")

        self._cards_played += 1

    # reset player info
    def reset_player_info(self):
        # set player info as waiting
        for index in range(0, 4):
            self._player_info[index].setText("Waiting for player")

    # change the card layout so that number is the player at the base of the
    # interface. player 0 is there by default.
    def rearrange_card_layout(self, number):
        b = self._card_layout[-number:]
        b.extend(self._card_layout[:-number])
        self._card_layout = b

        # same for self._player_info
        c = self._player_info[-number:]
        c.extend(self._player_info[:-number])
        self._player_info = c

    # check for new input from our Client regularly
    # this means that our GUI is not being blocked for waiting
    # also note that multiprocess poll is not the same as subprocess poll,
    # hence the need for Client on seperate process
    # see MsgTypes enum for details on message contents
    def handle_client_input(self):

        # slow down interaction for when you are playing with bots
        after = POLL_DELAY

        # check if game is still going
        if self._parent_conn == None:
            return

        # attempt to poll
        try:
            self._parent_conn.poll()
        except:
            # if we cannot poll it is because we could not connect to the server
            QMessageBox.information(self, '500', "Failed to connect")
            self.exit_to_menu()
            return

        # repeatedly poll if we have input from Client
        while self._parent_conn.poll():
            data = self.recieve_from_client()
            print(data)

            # recieve game details
            if data["type"] is MsgType.PLAYER:
                self._player = data["player"]
                self._players = data["players"]

                # reset details in case we are restarting
                self.reset_players_hands()
                self.reset_player_info()
                self.reset_cards_played()
                self.reset_bet_controls()

                # we want to arrange the self._card_layout indexes so that
                # index 0 becomes the new index self._player.
                self.rearrange_card_layout(self._player)

                # update deck on screen
                # we only will add the click event either during choosing the kitty
                # or when the first round begins
                self.update_player_hand(data["players"][self._player]["deck"])
                self.activate_card_controls(set=False)

                # update all info on screen
                for index in range(0, NUMBER_PLAYERS):
                    self._player_info[index].setText(
                        str(index + 1) + ": " +
                        data["players"][index]["name"] + os.linesep)

            # enable bet controls on our bet
            elif data["type"] is MsgType.BETOURS:
                # activate bet controls
                self.activate_bet_controls(set=True)

            elif data["type"] is MsgType.BETINFO:
                # reset error text and disable bet controls if this was us
                if data["player"] == self._player:
                    self.activate_bet_controls(set=False)

                # add betting text
                self._player_info[data["player"]].setText(
                    self._player_info[data["player"]].text() + os.linesep +
                    string_to_bet(data["bet"]))

                if MIN_TIME_BETWEEN_MOVES:
                    after = MIN_TIME_BETWEEN_MOVES
                    break

            # display why the users bet failed
            elif data["type"] is MsgType.BETFAILED:
                QMessageBox.information(self, '500', data["message"])

            # disable controls after betting is done
            elif data["type"] is MsgType.BETWON:
                self.activate_bet_controls(set=False)

                if MIN_TIME_BETWEEN_MOVES:
                    after = MIN_TIME_BETWEEN_MOVES
                    break

            # update the deck with the kitty cards
            elif data["type"] is MsgType.KITTYDECK:
                self._players[self._player]["deck"] = data["deck"]
                self.update_player_hand(data["deck"], setEvent=True)

            # activate card controls on kitty
            elif data["type"] is MsgType.KITTYCHOOSE:
                self.activate_card_controls(set=True)

            # we are required to choose a joker suit
            elif data["type"] is MsgType.JOKERCHOOSE:

                # create message box with suit choices
                msg = QMessageBox()
                msg.setWindowTitle('500')
                msg.setText('Choose a joker suit.')
                msg.addButton(QPushButton('Spades'), QMessageBox.YesRole)
                msg.addButton(QPushButton('Clubs'), QMessageBox.YesRole)
                msg.addButton(QPushButton('Diamonds'), QMessageBox.YesRole)
                msg.addButton(QPushButton('Hearts'), QMessageBox.YesRole)
                ret = msg.exec_()

                # send our chosen suit to the client
                if ret == 0:
                    ret = "S"
                elif ret == 1:
                    ret = "C"
                elif ret == 2:
                    ret = "D"
                elif ret == 3:
                    ret = "H"

                self.send_to_client(ret)

            # waiting on another player to choose joker suit
            elif data["type"] is MsgType.JOKERSTART:
                QMessageBox.information(self, '500',
                                        "A player is choosing joker suit.")

            # joker suit chosen
            elif data["type"] is MsgType.JOKERDONE:
                QMessageBox.information(
                    self, '500',
                    "The joker is a " + letter_to_suit(data["suit"]) + ".")

            # update bet (cards are now sorted by suit)
            elif data["type"] is MsgType.GAMESTART:
                self.reset_player_hand_after_kitty()
                self._players[self._player]["deck"] = data["deck"]
                self.update_player_hand(data["deck"], setEvent=True)

            # new round
            elif data["type"] is MsgType.ROUNDNEW:
                # reset number of cards played
                self.reset_cards_played()
                self._round = data["round"]

            # we can play a card, activate card controls
            elif data["type"] is MsgType.ROUNDCHOOSE:
                self.activate_card_controls(set=True)

            # card has been played
            elif data["type"] is MsgType.ROUNDCARDPLAYED:
                # remove card from the hand
                self.activate_card_controls(set=False)
                self.remove_card_from_hand(data["player"], data["card"])

                # play card to self._played_cards, updating winning text
                # if the winning card is different
                self.add_card_played(
                    data["card"], data["player"],
                    bool(self._card_winning != data["winningcard"]))
                self._card_winning = data["winningcard"]

                # only have a break if we are not next
                if MIN_TIME_BETWEEN_MOVES and \
                        not (data["player"] + 1) % NUMBER_PLAYERS == self._player:
                    after = MIN_TIME_BETWEEN_MOVES
                    break

            # player played bad card, show them a message
            elif data["type"] is MsgType.ROUNDBAD:
                QMessageBox.information(self, '500', data["message"])

            # also case that we are in the last round of play
            elif data["type"] is MsgType.ROUNDWON:
                # remove card from the hand
                self.activate_card_controls(set=False)
                self.remove_card_from_hand(data["player"], data["card"])

                # play card to self._played_cards
                self.add_card_played(
                    data["card"], data["player"],
                    bool(self._card_winning != data["winningcard"]))
                self._card_winning = None

                if MIN_TIME_BETWEEN_MOVES:
                    after = MIN_TIME_BETWEEN_MOVES
                    break

            # game over
            elif data["type"] is MsgType.GAMEOVER:
                QMessageBox.information(self, '500', "Game over!")
                self.exit_to_menu()
                return

        # repeat
        QtCore.QTimer.singleShot(after, self.handle_client_input)

    # when user presses join
    def join(self, port, password, ip, username):
        # communication
        self._parent_conn, child_conn = Pipe()

        # this call is blocking if the game loop method is in our controller class!
        self._client = Process(target=Client,
                               args=(
                                   [ip, port, password, username],
                                   child_conn,
                               ))
        self._client.start()

        # switch to game view
        self._stacked_layout.setCurrentIndex(2)

        # check for new data sent by Client in regular intervals
        QtCore.QTimer.singleShot(POLL_DELAY, self.handle_client_input)

    # sends data to the client, must be a string (non blocking)
    def send_to_client(self, data):
        if self._parent_conn != None:
            self._parent_conn.send(data)

    # recieves data from client (blocking)
    def recieve_from_client(self):
        if self._parent_conn != None:
            return self._parent_conn.recv()

        return None

    # when user presses the go button
    def create_game(self):

        # these details are always required details
        port = str(self.get_port())
        if port == "" or port == "0":
            QMessageBox.information(self, '500', "Please enter a valid port")
            return

        username = self.get_username()
        if username == "":
            QMessageBox.information(self, '500', "Please enter a username")
            return

        # rest of the details are different for each options type
        if self._options_type == 0:
            password = "******"
            ptypes = "0222"
            ip = get_localhost_ip()
            self.create_server(port, password, ptypes)

        else:
            # get password for next 2 cases
            password = self.get_password()
            if password == "":
                QMessageBox.information(self, '500', "Please enter a password")
                return

            if self._options_type == 1:
                ip = self.get_ip()

                # check if ip is valid, ensure it is seperated by 4 dots and
                # all are numbers between 0 and 255
                check = ip.split('.')
                error = 0

                if len(check) == 4:
                    for index in range(0, 4):
                        if (check[index].isnumeric() == True
                                and int(check[index]) >= 0
                                and int(check[index]) < 256):

                            error += 1

                if error != 4:
                    QMessageBox.information(self, '500',
                                            "Please enter a valid IP address")
                    return

            elif self._options_type == 2:
                ip = get_localhost_ip()
                ptypes = ["0"]

                for index in range(0, 3):
                    ptypes.append(str(self.get_player_type(index)))

                self.create_server(port, password, ''.join(ptypes))

        self.join(port, password, ip, username)

    # ensure we exit only after cleaning up
    def closeEvent(self, event):
        self.close_subprocesses()
        return QWidget.closeEvent(self, event)

    # closes server and client subprocesses
    def close_subprocesses(self):
        if self._server != None:
            self._server.kill()
            self._server = None
            self._parent_conn = None
            print("Server Terminated")

        if self._client != None:
            self._client.terminate()
            self._client = None
            print("Client Terminated")

    # change layout and close server and client subprocesses
    def exit_to_menu(self):
        self._stacked_layout.setCurrentIndex(0)
        self.close_subprocesses()
        self.reset()

    # reset game variables
    def reset(self):
        # reset all parts of gui
        self.reset_player_info()
        self.reset_bet_controls()
        self.reset_cards_played()
        self.reset_player_hand_after_kitty()
        self.activate_card_controls(set=False)

        # the below resets the hand locations, so ensure all card
        # related resetting done before this
        self.reset_players_hands()

        # reset all player details
        self._player = 0
        self._players = None
        self._round = None
        self._cards_played = 0

    # creates the server
    def create_server(self, port, password, playertypes):

        # create server args
        srvargs = ["./server", port, password, playertypes]

        # create server
        self._server = subprocess.Popen(srvargs, stdout=subprocess.DEVNULL)
        print("Server Created.")
示例#11
0
class QRuleEditor(QDialog):
    def __init__(self, project, editor,
                 rule):  # Rule is some fontFeatures object
        self.project = project
        self.editor = editor
        self.inputslots = []
        self.precontextslots = []
        self.postcontextslots = []
        self.outputslots = []
        self.buffer_direction = "RTL"
        self.buffer_script = "Latin"
        self.all_valuerecord_editors = []
        self.index = None
        if rule:
            self.backup_rule = Rule.fromXML(rule.toXML())  # Deep copy
        else:
            self.backup_rule = None

        super(QRuleEditor, self).__init__()

        splitter = QSplitter()
        self.slotview = QHBoxLayout()
        scroll = QScrollArea()
        scroll.setLayout(self.slotview)

        self.outputview_before = QBufferRenderer(
            project, VariationAwareBuffer(self.project.font))
        self.outputview_after = QBufferRenderer(
            project, VariationAwareBuffer(self.project.font))
        self.before_after = QWidget()
        self.before_after_layout_v = QVBoxLayout()

        self.asFea = QLabel()

        featureButtons = QWidget()
        self.featureButtonLayout = QHBoxLayout()
        featureButtons.setLayout(self.featureButtonLayout)
        self.selectedFeatures = []

        layoutarea = QWidget()
        self.before_after_layout_h = QHBoxLayout()
        self.before_after_layout_h.addWidget(self.outputview_before)
        self.before_after_layout_h.addWidget(self.outputview_after)
        layoutarea.setLayout(self.before_after_layout_h)

        if self.project.variations:
            self.master_selection = QComboBox()
            for mastername in self.project.variations.masters:
                self.master_selection.addItem(mastername)
            self.master_selection.currentTextChanged.connect(
                self.masterChanged)
            self.before_after_layout_v.addWidget(self.master_selection)
        else:
            self.master_selection = None

        self.before_after_layout_v.addWidget(featureButtons)
        self.before_after_layout_v.addWidget(self.asFea)
        self.before_after_layout_v.addWidget(layoutarea)

        self.before_after.setLayout(self.before_after_layout_v)

        splitter.setOrientation(Qt.Vertical)
        splitter.addWidget(scroll)

        splitter.addWidget(self.before_after)
        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        for button in buttons.buttons():
            button.setDefault(False)
            button.setAutoDefault(False)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        v_box_1 = QVBoxLayout()
        self.setLayout(v_box_1)
        v_box_1.addWidget(splitter)
        v_box_1.addWidget(buttons)
        self.setRule(rule)

    @property
    def currentMaster(self):
        if not self.master_selection:
            return None
        return self.master_selection.currentText()

    def masterChanged(self):
        for qvre in self.all_valuerecord_editors:
            qvre.change_master(self.currentMaster)
        self.resetBuffer()

    def keyPressEvent(self, evt):
        return

    def accept(self):
        self.editor.fontfeaturespanel.lookuplist.update(self.index)
        self.editor.setWindowModified(True)
        self.editor.showDebugger()

    def reject(self):
        for k in dir(self.backup_rule):
            self.rule = getattr(self.backup_rule, k)
        self.editor.fontfeaturespanel.lookuplist.update()
        self.editor.showDebugger()

    def setRule(self, rule, index=None):
        self.rule = rule
        self.index = index
        self.arrangeSlots()
        self.representative_string = self.makeRepresentativeString()
        self.resetBuffer()

    @property
    def location(self):
        sourceIndex = list(self.project.variations.masters.keys()).index(
            self.currentMaster)
        return self.project.variations.designspace.sources[
            sourceIndex].location

    def resetBuffer(self):
        if self.rule:
            try:
                self.asFea.setText(self.rule.asFea())
            except Exception as e:
                print("Can't serialize", e)
        self.outputview_before.set_buf(self.makeBuffer("before"))
        self.outputview_after.set_buf(self.makeBuffer("after"))
        if self.currentMaster:
            self.outputview_before.set_location(self.location)
            self.outputview_after.set_location(self.location)

    @pyqtSlot()
    def changeRepresentativeString(self):
        l = self.sender()
        if l.text().startswith("@"):
            self.representative_string[
                l.slotnumber] = self.project.fontfeatures.namedClasses[
                    l.text()[1:]][0]
        else:
            self.representative_string[l.slotnumber] = l.text()

        self.resetBuffer()

    @pyqtSlot()
    def replacementChanged(self):
        l = self.sender()
        replacements = l.text().split()
        self.rule.replacement = [[x] for x in replacements]
        self.resetBuffer()

    @pyqtSlot()
    def addGlyphToSlot(self):
        l = self.sender()
        glyphname = l.text()
        # Check for class names
        if (glyphname.startswith("@") and glyphname[1:]
                in self.project.fontfeatures.namedClasses.keys()):
            # It's OK
            pass
        elif glyphname not in self.project.font.keys():
            print(f"{glyphname} not found")
            l.setText("")
            return
        print("Adding ", glyphname)
        l.owner.contents[l.owner.slotindex].append(glyphname)
        self.arrangeSlots()
        self.representative_string = self.makeRepresentativeString()
        self.resetBuffer()

    @pyqtSlot()
    def removeGlyphFromSlot(self):
        l = self.sender()
        del l.contents[l.slotindex][l.indexWithinSlot]
        self.arrangeSlots()
        self.representative_string = self.makeRepresentativeString()
        self.resetBuffer()

    @pyqtSlot()
    def addRemoveSlot(self):
        sender = self.sender()
        action = sender.text()
        if action == "<+":
            sender.contents.insert(0, [])
            # If these are input glyphs, add another replacement etc.
            if sender.contents == self.rule.shaper_inputs():
                if isinstance(self.rule, Positioning):
                    self.rule.valuerecords.insert(0, ValueRecord())
                elif (isinstance(self.rule, Substitution)
                      and len(self.rule.shaper_inputs()) == 1):
                    self.rule.replacement.insert(0, [])
                elif isinstance(self.rule, Chaining):
                    self.rule.lookups.insert(0, [])
        elif action == "+>":
            sender.contents.append([])
            # If these are input glyphs, add another replacement etc.
            if sender.contents == self.rule.shaper_inputs():
                if isinstance(self.rule, Positioning):
                    self.rule.valuerecords.append(ValueRecord())
                elif (isinstance(self.rule, Substitution)
                      and len(self.rule.shaper_inputs()) == 1):
                    self.rule.replacement.append([])
                elif isinstance(self.rule, Chaining):
                    self.rule.lookups.append([])

        elif action == "-":
            del sender.contents[self.sender().ix]
        self.arrangeSlots()
        self.representative_string = self.makeRepresentativeString()
        self.resetBuffer()

    def makeASlot(self, slotnumber, contents, style=None, editingWidgets=None):
        for ix, glyphslot in enumerate(contents):
            slot = QWidget()
            slotLayout = QVBoxLayout()
            if style:
                slot.setStyleSheet(style)

            scroll = QScrollArea()
            scroll.setWidgetResizable(True)
            scrollWidget = QWidget()
            scrollLayout = QVBoxLayout()
            scrollWidget.setLayout(scrollLayout)
            scroll.setWidget(scrollWidget)
            for ixWithinSlot, glyph in enumerate(glyphslot):
                glyphHolder = QWidget()
                glyphHolderLayout = QHBoxLayout()
                glyphHolder.setLayout(glyphHolderLayout)
                l = QPushButton(glyph)
                l.setDefault(False)
                l.setAutoDefault(False)
                l.slotnumber = slotnumber
                l.clicked.connect(self.changeRepresentativeString)
                glyphHolderLayout.addWidget(l)

                remove = QPushButton("x")
                remove.slotindex = ix
                remove.indexWithinSlot = ixWithinSlot
                remove.contents = contents
                remove.clicked.connect(self.removeGlyphFromSlot)
                glyphHolderLayout.addWidget(remove)
                scrollLayout.addWidget(glyphHolder)

            slotLayout.addWidget(scroll)

            # This is the part that adds a new glyph to a slot
            newglyph = QGlyphName(self.project, allow_classes=True)
            newglyph.slotindex = ix
            newglyph.contents = contents
            newglyph.glyphline.returnPressed.connect(self.addGlyphToSlot)
            slotLayout.addWidget(newglyph)

            slotLayout.addStretch()
            if editingWidgets and ix < len(editingWidgets):
                slotLayout.addWidget(editingWidgets[ix])

            pushbuttonsArea = QWidget()
            pushbuttonsLayout = QHBoxLayout()
            pushbuttonsArea.setLayout(pushbuttonsLayout)
            if ix == 0:
                addASlotLeft = QPushButton("<+")
                addASlotLeft.contents = contents
                addASlotLeft.clicked.connect(self.addRemoveSlot)
                pushbuttonsLayout.addWidget(addASlotLeft)
            pushbuttonsLayout.addStretch()
            if not (editingWidgets and len(contents) == 1):
                removeASlot = QPushButton("-")
                removeASlot.contents = contents
                removeASlot.ix = ix
                removeASlot.clicked.connect(self.addRemoveSlot)
                pushbuttonsLayout.addWidget(removeASlot)
            pushbuttonsLayout.addStretch()
            if ix == len(contents) - 1:
                addASlotRight = QPushButton("+>")
                addASlotRight.contents = contents
                addASlotRight.clicked.connect(self.addRemoveSlot)
                pushbuttonsLayout.addWidget(addASlotRight)
            slotLayout.addWidget(pushbuttonsArea)

            slotnumber = slotnumber + 1

            slot.setLayout(slotLayout)
            self.slotview.addWidget(slot)
        return slotnumber

    def lookupCombobox(self, current, warning):
        c = QComboBox()
        c.warning = warning
        names = [
            x.name for x in self.project.fontfeatures.routines
            if not hasattr(x, "comment")
        ]
        names = ["--- No lookup ---"] + names
        for name in names:
            c.addItem(name)
        if current in names:
            c.setCurrentIndex(names.index(current))
        self.setComboboxWarningIfNeeded(c)
        return c

    @pyqtSlot()
    def chainingLookupChanged(self):
        l = self.sender()
        if l.currentIndex() == 0:
            self.rule.lookups[l.ix] = []
        else:
            self.rule.lookups[l.ix] = [RoutineReference(name=l.currentText())]
        self.setComboboxWarningIfNeeded(l)
        self.resetBuffer()

    def changesGlyphstringLength(self, routine, depth=1):
        if depth > 10:
            return False
        for r in routine.rules:
            if isinstance(r,
                          Substitution) and len(r.input) != len(r.replacement):
                return True
            elif isinstance(r, Chaining):
                for lus in r.lookups:
                    for l in (lus or []):
                        if self.changesGlyphstringLength(l.routine, depth + 1):
                            return True
        return False

    def setComboboxWarningIfNeeded(self, combobox):
        # Find routine
        rname = combobox.currentText()
        warningNeeded = False
        if rname:
            routine = None
            for r in self.project.fontfeatures.routines:
                if r.name == rname:
                    routine = r
        if routine and self.changesGlyphstringLength(routine):
            stdicon = self.style().standardIcon(QStyle.SP_MessageBoxWarning)
            combobox.warning.setPixmap(
                stdicon.pixmap(stdicon.actualSize(QSize(16, 16))))
            combobox.warning.setToolTip(
                "<qt>This lookup may change the length of the glyph stream. Subsequent lookups may not fire at the glyph slots you expect.</qt>"
            )
        else:
            combobox.warning.clear()
            combobox.warning.setToolTip("")

    def addPrecontext(self):
        self.rule.precontext = [[]]
        self.arrangeSlots()

    def addPostcontext(self):
        self.rule.postcontext = [[]]
        self.arrangeSlots()

    def makeEditingWidgets(self):
        editingWidgets = []
        if isinstance(self.rule, Substitution):
            replacements = [x[0] for x in self.rule.replacement if x]
            widget = QGlyphName(self.project,
                                multiple=len(self.rule.shaper_inputs()) < 2)
            widget.setText(" ".join(replacements) or "")
            widget.position = 0
            widget.returnPressed.connect(self.replacementChanged)
            editingWidgets.append(widget)
        else:
            for ix, i in enumerate(self.rule.shaper_inputs()):
                if isinstance(self.rule, Positioning):
                    widget = QValueRecordEditor(self.rule.valuerecords[ix],
                                                vf=self.project.variations,
                                                master=self.currentMaster)
                    widget.changed.connect(self.resetBuffer)
                    editingWidgets.append(widget)
                    self.all_valuerecord_editors.append(widget)
                elif isinstance(self.rule, Chaining):
                    lookup = self.rule.lookups[ix] and self.rule.lookups[ix][
                        0].name
                    w = QWidget()
                    wl = QHBoxLayout(w)
                    w.setLayout(wl)
                    warning = QLabel()
                    widget = self.lookupCombobox(lookup, warning)
                    widget.ix = ix
                    widget.currentTextChanged.connect(
                        self.chainingLookupChanged)
                    wl.addWidget(widget)
                    wl.addWidget(warning)
                    editingWidgets.append(w)
        return editingWidgets

    def clearLayout(self, layout):
        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                widget = item.widget()
                if widget is not None:
                    widget.deleteLater()
                else:
                    self.clearLayout(item.layout())

    def arrangeSlots(self):
        self.all_valuerecord_editors = []
        self.clearLayout(self.slotview)
        if not self.rule:
            return

        slotnumber = 0

        if not hasattr(self.rule, "precontext") or not self.rule.precontext:
            widget = QPushButton("<<+")
            widget.clicked.connect(self.addPrecontext)
            self.slotview.addWidget(widget)
        else:
            self.slotview.addStretch()
            slotnumber = self.makeASlot(slotnumber, self.rule.precontext,
                                        precontext_style)

        editingWidgets = self.makeEditingWidgets()
        slotnumber = self.makeASlot(slotnumber,
                                    self.rule.shaper_inputs(),
                                    editingWidgets=editingWidgets)

        if not hasattr(self.rule, "postcontext") or not self.rule.postcontext:
            widget = QPushButton("+>>")
            widget.clicked.connect(self.addPostcontext)
            self.slotview.addWidget(widget)
        else:
            self.makeASlot(slotnumber, self.rule.postcontext,
                           postcontext_style)

        self.slotview.addStretch()

    def makeRepresentativeString(self):
        inputglyphs = []
        if not self.rule:
            return inputglyphs
        # "x and x[0]" thing because slots may be empty if newly added
        if hasattr(self.rule, "precontext"):
            inputglyphs.extend([x and x[0] for x in self.rule.precontext])

        inputglyphs.extend([x and x[0] for x in self.rule.shaper_inputs()])

        if hasattr(self.rule, "postcontext"):
            inputglyphs.extend([x and x[0] for x in self.rule.postcontext])

        representative_string = [x for x in inputglyphs if x]
        for ix, g in enumerate(representative_string):
            if (g.startswith("@") and g[1:]
                    in self.project.fontfeatures.namedClasses.keys()):
                representative_string[
                    ix] = self.project.fontfeatures.namedClasses[g[1:]][0]

        # We use this representative string to guess information about
        # how the *real* shaping process will take place; buffer direction
        # and script, and hence choice of complex shaper, and hence from
        # that choice of features to be processed.
        unicodes = [
            self.project.font.codepointForGlyph(x)
            for x in representative_string
        ]
        unicodes = [x for x in unicodes if x]
        tounicodes = "".join(map(chr, unicodes))
        bufferForGuessing = Buffer(self.project.font, unicodes=tounicodes)
        self.buffer_direction = bufferForGuessing.direction
        self.buffer_script = bufferForGuessing.script
        # print("Guessed buffer direction ", self.buffer_direction)
        # print("Guessed buffer script ", self.buffer_script)
        shaper = Shaper(self.project.fontfeatures, self.project.font)
        bufferForGuessing = Buffer(self.project.font,
                                   glyphs=representative_string)
        shaper.execute(bufferForGuessing)
        self.availableFeatures = []
        for stage in shaper.stages:
            if not isinstance(stage, list):
                continue
            for f in stage:
                if (f not in self.availableFeatures
                        and f in self.project.fontfeatures.features):
                    self.availableFeatures.append(f)
        self.makeFeatureButtons()

        return representative_string

    def makeFeatureButtons(self):
        self.clearLayout(self.featureButtonLayout)
        for f in self.availableFeatures:
            self.selectedFeatures.append(f)
            featureButton = QCheckBox(f)
            featureButton.setChecked(True)
            featureButton.stateChanged.connect(self.resetBuffer)
            self.featureButtonLayout.addWidget(featureButton)

    def makeShaperFeatureArray(self):
        features = []
        for i in range(self.featureButtonLayout.count()):
            item = self.featureButtonLayout.itemAt(i).widget()
            features.append({"tag": item.text(), "value": item.isChecked()})
        return features

    def makeBuffer(self, before_after="before"):
        buf = VariationAwareBuffer(
            self.project.font,
            direction=self.buffer_direction,
        )
        if self.project.variations:
            buf.location = self.location
            buf.vf = self.project.variations
        buf.items = [
            VariationAwareBufferItem.new_glyph(g, self.project.font, buf)
            for g in self.representative_string
        ]
        shaper = Shaper(self.project.fontfeatures, self.project.font)

        shaper.execute(buf, features=self.makeShaperFeatureArray())
        routine = Routine(rules=[self.rule])
        # print("Before shaping: ", buf.serialize())
        if before_after == "after" and self.rule:
            print("Before application: ", buf.serialize())
            print(self.rule.asFea())
            buf.clear_mask()  # XXX
            try:
                routine.apply_to_buffer(buf)
            except Exception as e:
                print("Couldn't shape: " + str(e))
            print("After application: ", buf.serialize())
        return buf
示例#12
0
class Connect_Directions(QObject):
    """
    This class is used to connect the directions modifications at the
    GUI level. It modifies the module according to the newly selected
    parameter value.
    """

    signal_paramChanged = pyqtSignal(str, list)

    # ----------------------------------------------------------------------
    def __init__(self, paramName, chosen_value, all_Values, nb_directions):
        """
        Constructor
        """
        super().__init__()
        self.paramName = paramName
        self.l = QHBoxLayout()
        self.chosen_value = chosen_value

        self.create_the_comboBoxes(chosen_value, all_Values, nb_directions)

    # ----------------------------------------------------------------------
    def create_the_comboBoxes(self, chosen_value, all_Values, nb_directions):
        """
        Creates nb_directions directions, list the possible values and select the chosen_value.
        
        paramName = Name of the parameter corresponding to the widget to create 
        chosen_value = the subject's specific parameter values.
        all_Values = list of all possible values for a parameter
        nb_directions = number of directions to add.
        """
        nb_val = range(len(chosen_value))
        for i in nb_val:
            self.l.addWidget(
                self.add_To_ComboBox(all_Values, chosen_value[i], i))

            # Add a vertical separator
            if i != nb_directions:
                add_v_separator(self.l)

        nb_val = range(len(chosen_value), nb_directions)
        for i in nb_val:
            self.l.addWidget(self.add_To_ComboBox(all_Values, None, i))

            # Add a vertical separator
            if i != nb_val[-1]:
                add_v_separator(self.l)

    # ----------------------------------------------------------------------
    def add_To_ComboBox(self, values, chosenValue, pos):
        """
        Add the possibles values found in the structure file to a QComboBox.
        Highlight the subject's specific value.
        values = list of values.
        chosenValue = subject's specific value.
        pos = QComboBox position in the directions list
        """
        templateChoices = QComboBox_Directions(pos)

        # Iterates over the possible choices
        for val in values:
            templateChoices.addItem(str(val), val)
            if val == chosenValue:
                templateChoices.setCurrentText(val)

        templateChoices.signal_paramChanged[int,
                                            object].connect(self.on_modify)

        return templateChoices

    #----------------------------------------------------------------------
    def clear_hBoxLayout(self):
        """
        #Removes all the widgets added to the layout
        """
        for i in reversed(range(self.l.count())):
            self.l.itemAt(i).widget().setParent(None)

    @pyqtSlot(str, str)
    #----------------------------------------------------------------------
    def on_new_tdef_file(self, key, trigger_file):
        """
        Update the QComboBox with the new events from the new tdef file.
        """
        self.clear_hBoxLayout()
        tdef = trigger_def(trigger_file)
        nb_directions = 4
        #  Convert 'None' to real None (real None is removed when selected in the GUI)
        tdef_values = [None if i == 'None' else i for i in list(tdef.by_name)]
        self.create_the_comboBoxes(self.chosen_value, tdef_values,
                                   nb_directions)

    @pyqtSlot(int, object)
    # ----------------------------------------------------------------------
    def on_modify(self, pos, new_Value):
        """
        Slot connected to comboBox param value change
        
        pos = QComboBox position in the directions list
        new_value = direction new_value
        """
        if pos >= len(self.chosen_value):
            self.chosen_value.append(new_Value)
        else:
            self.chosen_value[pos] = (new_Value)

        try:
            self.chosen_value.remove(None)
        except:
            pass

        self.signal_paramChanged[str, list].emit(self.paramName,
                                                 self.chosen_value)
示例#13
0
class App(QDialog):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        self.title = "DALI app data regressor"
        self.attriNum = 0
        self.currOutcome = " "

        # initialize the attribute list
        self.attriList = [
            "heightInches", "happiness", "stressed", "sleepPerNight",
            "socialDinnerPerWeek", "alcoholDrinksPerWeek", "caffeineRating",
            "affiliated", "numOfLanguages", "gymPerWeek", "hoursOnScreen"
        ]

        # initialize the variable list
        self.variabList = []

        # initialize the regression results
        self.res = Result()

        # create group boxes
        self.createOutcomeBox()
        self.createScrollBox()
        self.createAttriLabelBox()
        self.createErrorBox()
        self.createCalcBox()
        self.createResultsLabel()
        self.createModelLabel()
        self.createRMSEbox()
        self.createErrorTwo()
        self.createResuScroll()
        self.createPredictBox()
        self.createOutcomePred()

        # layout all the boxes
        mainLayout = QGridLayout()
        mainLayout.addLayout(self.outcomeBox, 0, 0)
        mainLayout.addLayout(self.attriLabelBox, 1, 0)
        mainLayout.addLayout(self.errorBox, 2, 0)
        mainLayout.addLayout(self.scrollBox, 3, 0)
        mainLayout.addLayout(self.calcBox, 4, 0)
        mainLayout.addLayout(self.resBox, 0, 1)
        mainLayout.addLayout(self.modelBox, 1, 1)
        mainLayout.addLayout(self.rmseBox, 2, 1)
        mainLayout.addLayout(self.errorTwo, 3, 1)
        mainLayout.addLayout(self.resuScroll, 4, 1)
        mainLayout.addLayout(self.predBox, 5, 1)
        mainLayout.addLayout(self.outcomePred, 6, 1)

        self.setLayout(mainLayout)

        # initialize the UI
        self.initUI()

    # initializes the UI
    def initUI(self):
        self.setWindowTitle(self.title)

        self.show()

    # create a outcome selector box
    def createOutcomeBox(self):
        self.outcomeBox = QHBoxLayout()

        #create combo box and label widgets
        outcomeCombo = QComboBox()
        outcomeCombo.addItems(self.attriList)

        outcomeLabel = QLabel("&Outcome variable:")
        outcomeLabel.setBuddy(outcomeCombo)

        # add all the widgets to the box
        self.outcomeBox.addWidget(outcomeLabel)
        self.outcomeBox.addStretch(1)
        self.outcomeBox.addWidget(outcomeCombo)

    # create a box that contains buttons and labels
    def createAttriLabelBox(self):
        self.attriLabelBox = QHBoxLayout()

        # create an attribute label
        attributeLab = QLabel("Attributes:")

        # create both add and remove buttons
        addButton = QPushButton('Add', self)
        addButton.setToolTip('Adds more attribute boxes')
        addButton.clicked.connect(self.clickAdd)

        rmButton = QPushButton('Remove', self)
        rmButton.setToolTip('Removes more attribute boxes')
        rmButton.clicked.connect(self.clickRM)

        # add all the widgets to the box
        self.attriLabelBox.addWidget(attributeLab)
        self.attriLabelBox.addStretch(1)
        self.attriLabelBox.addWidget(addButton)
        self.attriLabelBox.addWidget(rmButton)

    # create an error box
    def createErrorBox(self):
        self.errorBox = QHBoxLayout()

        # create error label
        errorLabel = QLabel(' ')

        self.errorBox.addWidget(errorLabel)

    # creates a scroll box for attribute boxes
    def createScrollBox(self):
        self.scrollBox = QVBoxLayout()

        # create central widget
        central = QWidget()

        # create scroll area widget
        scrollArea = QScrollArea()
        scrollArea.setWidget(central)
        scrollArea.setWidgetResizable(True)

        # create box layout within the box
        scrollInbox = QVBoxLayout(central)

        # set box layout
        self.scrollBox.addWidget(scrollArea)

    # create box that contains calculate button
    def createCalcBox(self):
        self.calcBox = QHBoxLayout()

        # create calculate button
        modelButton = QPushButton('Model Regression', self)
        modelButton.setToolTip("Calculates regression models")
        modelButton.clicked.connect(self.clickModel)

        self.calcBox.addWidget(modelButton)

    # create box that contains the results label
    def createResultsLabel(self):
        self.resBox = QHBoxLayout()

        # create label
        resLabel = QLabel("Results:")

        self.resBox.addWidget(resLabel)

    # create box that contains the model label
    def createModelLabel(self):
        self.modelBox = QHBoxLayout()

        # create label
        modelLabel = QLabel("Model used:")
        self.modelBox.addWidget(modelLabel)

    # create box that contains rmse label
    def createRMSEbox(self):
        self.rmseBox = QHBoxLayout()

        rmseLabel = QLabel("RMSE:")
        self.rmseBox.addWidget(rmseLabel)

    # create box that contains error label 2
    def createErrorTwo(self):
        self.errorTwo = QHBoxLayout()

        errorTwoLabel = QLabel(" ")
        self.errorTwo.addWidget(errorTwoLabel)

    # creates a second scroll box for attribute boxes
    def createResuScroll(self):
        self.resuScroll = QVBoxLayout()

        # create central widget
        central2 = QWidget()

        # create scroll area widget
        scrollSpace = QScrollArea()
        scrollSpace.setWidget(central2)
        scrollSpace.setWidgetResizable(True)

        # create box layout within the box
        scrollInbox = QVBoxLayout(central2)

        # add the scroll space to the box
        self.resuScroll.addWidget(scrollSpace)

    # creates a box for predict button
    def createPredictBox(self):
        self.predBox = QHBoxLayout()

        # create predict button
        predButton = QPushButton('Predict', self)
        predButton.setToolTip("Predicts outcome based on model")
        predButton.clicked.connect(self.clickPredict)

        self.predBox.addWidget(predButton)

    # create box that contains outcome prediction
    def createOutcomePred(self):
        self.outcomePred = QHBoxLayout()

        outcomeLabel = QLabel('Outcome prediction:')

        self.outcomePred.addWidget(outcomeLabel)

    # what to do when the add button is pushed
    @pyqtSlot()
    def clickAdd(self):
        # if there are too many attribute boxes, display error
        if self.attriNum <= 9:
            # add a new combo box
            newCombo = QComboBox()
            newCombo.addItems(self.attriList)
            self.scrollBox.itemAt(0).widget().widget().layout().addWidget(
                newCombo)
            self.attriNum += 1

        else:
            error1 = "Error: Too many attributes. Leave as be or decrease."
            self.errorBox.itemAt(0).widget().setText(error1)

    # what to do when the remove button is pushed
    @pyqtSlot()
    def clickRM(self):
        # if there are boxes to remove, remove them
        if self.attriNum > 0:
            # clear the error box
            error0 = " "
            self.errorBox.itemAt(0).widget().setText(error0)

            # remove the newest combo box
            self.scrollBox.itemAt(0).widget().widget().layout().itemAt(
                self.attriNum - 1).widget().deleteLater()
            self.attriNum -= 1

    # what to do when the modelling button is pushed
    @pyqtSlot()
    def clickModel(self):
        # make sure there are attributes to model with
        if self.attriNum > 0:
            # make sure there are no duplicates with either the outcome variable or the attributes
            self.variabList.clear()
            self.variabList.append(
                self.outcomeBox.itemAt(2).widget().currentText())

            noDupli = True
            i = 0

            # while there attributes to be appended and there are no duplicates
            while i < self.attriNum and noDupli:
                # append the selected attribute
                comboText = self.scrollBox.itemAt(0).widget().widget().layout(
                ).itemAt(i).widget().currentText()
                self.variabList.append(comboText)

                i += 1

                # if the length of the set of the current list is not equal to the length of the current list
                if len(self.variabList) != len(set(self.variabList)):
                    noDupli = False

            # if there was no duplicates, proceed with the current list of outcome variable and attributes
            if noDupli:
                # clear the error box
                error0 = " "
                self.errorBox.itemAt(0).widget().setText(error0)

                # if there was only one attribute selected perform single attribute regression
                if self.attriNum == 1:
                    self.res = singleAttriReg(self.variabList[0],
                                              self.variabList[1])

                # otherwise perform multi attribute regression
                else:
                    attributes = self.variabList[1:]
                    self.res = multiAttriReg(attributes, self.variabList[0])

                # post the results
                model = "Model used: " + self.res.strat
                rmse = "RMSE: " + str(self.res.rmse)

                self.modelBox.itemAt(0).widget().setText(model)
                self.rmseBox.itemAt(0).widget().setText(rmse)

                # clear the previous resuScroll
                for i in reversed(
                        range(
                            self.resuScroll.itemAt(
                                0).widget().widget().layout().count())):
                    self.resuScroll.itemAt(0).widget().widget().layout(
                    ).itemAt(i).widget().setParent(None)

                # set the current outcome variable so it doesn't get affected by changing
                # on the screen elsewhere
                self.currOutcome = self.variabList[0]

                # create appropriate attribute variable input editors
                for i in range(self.attriNum):
                    placeholder = QWidget()

                    inputBox = QHBoxLayout()
                    attributes = self.variabList[1:]

                    label = QLabel(attributes[i] + ": ")
                    lineEdit = QLineEdit()
                    inputBox.addWidget(label)
                    inputBox.addWidget(lineEdit)

                    placeholder.setLayout(inputBox)

                    self.resuScroll.itemAt(
                        0).widget().widget().layout().addWidget(placeholder)

            # if there were duplicates post error
            else:
                error3 = "Error: no duplicate variables allowed"
                self.errorBox.itemAt(0).widget().setText(error3)

        else:
            error2 = "Error: cannot model without attribute variables"
            self.errorBox.itemAt(0).widget().setText(error2)

    # what to do when the prediction button is pushed
    @pyqtSlot()
    def clickPredict(self):
        attriCount = self.resuScroll.itemAt(
            0).widget().widget().layout().count()
        newAttriList = []

        # make sure there are attributes to use to predict
        if attriCount > 0:
            # make sure all the inputted texts are integers
            numbers = True
            for j in range(attriCount):
                try:
                    num = int(
                        self.resuScroll.itemAt(0).widget().widget().layout().
                        itemAt(j).widget().layout().itemAt(1).widget().text())
                    newAttriList.append(num)
                except ValueError:
                    numbers = False

            # if all inputs were integers
            if numbers:
                # clear error message
                notErr = " "
                self.errorTwo.itemAt(0).widget().setText(notErr)

                # predict
                newAttriList = [newAttriList]

                # to account for special cases where polynomials screw up the code
                if self.res.strat == "polynomial regression":
                    poly = PolynomialFeatures(5)
                    newAttriList = poly.fit_transform(newAttriList)
                    prediction = self.res.reg.predict(newAttriList)

                else:
                    prediction = self.res.reg.predict(newAttriList)

                # if there is only 1 attribute
                if attriCount == 1:
                    # set results of prediction
                    predResult = "Outcome - " + self.currOutcome + ": " + str(
                        round(prediction[0][0], 4))
                    self.outcomePred.itemAt(0).widget().setText(predResult)

                # if there are more than 1 attribute
                else:
                    # set results of prediction
                    predResult = "Outcome - " + self.currOutcome + ": " + str(
                        round(prediction[0], 4))
                    self.outcomePred.itemAt(0).widget().setText(predResult)

            # set error accordingly
            else:
                error5 = "Error: One or more inputs not integers"
                self.errorTwo.itemAt(0).widget().setText(error5)

        # set error accordingly
        else:
            error4 = "Error: No attributes to use to predict."
            self.errorTwo.itemAt(0).widget().setText(error4)
示例#14
0
class cover_search_widget(QWidget):
    finished = pyqtSignal()
    canceled = pyqtSignal()
    result = pyqtSignal(QPixmap)
    _arrow_style = 'background-color: {}; border: 0'.format(BACKGROUND_COLOR)
    _button_style = '''
        QPushButton {
            background-color: #888;
            color: #F7F7F7;
            border: 0;
            width: 6em;
            height: 2em;
            border-radius: 5px;
        }
        QPushButton:hover {
            background-color: #666;
            color: #FFFFFF;
        }
        QPushButton:pressed {
            background-color: #444;
            color: #FFFFFF;
        }
    '''

    def __init__(self, artist_name, album_name, parent=None):
        super(cover_search_widget, self).__init__(parent)

        self._artist_name = artist_name
        self._album_name = album_name

        self.setWindowTitle('{}: {}'.format(artist_name, album_name))
        self.resize(SEARCH_WINDOW_WIDTH, SEARCH_WINDOW_HEIGHT)
        self.setStyleSheet('background-color: {}'.format(BACKGROUND_COLOR))

        self._cover_start_index = 1
        self._selected_cover_index = -1
        self._cover_pixmaps = []
        self._cover_resolutions = []

        self._init_layout()
        self.setLayout(self._layout)

        self._set_state_loading()

    def _init_layout(self):
        self._layout = QVBoxLayout()
        self._layout.setContentsMargins(0, 0, 0, 30)

        self._init_search_layout()
        self._layout.addLayout(self._search_layout)

        self._init_button_layout()
        self._layout.addLayout(self._button_layout)

    def _init_search_layout(self):
        self._search_layout = QHBoxLayout()
        self._search_layout.setContentsMargins(5, 30, 5, 10)

        left_pixmap = QPixmap('icons/prev_icon.png')
        left_dummy_pixmap = QPixmap('icons/prev_dummy_icon.png')
        self._left_icon = QIcon(left_pixmap)
        self._left_dummy_icon = QIcon(left_dummy_pixmap)
        left = QPushButton('')
        left.setStyleSheet(self._arrow_style)
        left.setIcon(self._left_dummy_icon)
        left.setIconSize(QSize(72, 72))
        self._search_layout.addWidget(left, alignment=Qt.AlignCenter)

        self._search_layout.addStretch(1)

        self._init_cover_layout()
        for cover_layout in self._cover_layouts:
            self._search_layout.addLayout(cover_layout)

        self._search_layout.addStretch(1)

        right_pixmap = QPixmap('icons/next_icon.png')
        right = QPushButton('')
        right.setStyleSheet(self._arrow_style)
        right.setIcon(QIcon(right_pixmap))
        right.setIconSize(QSize(72, 72))
        self._search_layout.addWidget(right, alignment=Qt.AlignCenter)

        for cover_layout in self._cover_layouts:
            left.clicked.connect(cover_layout.itemAt(0).widget().unselected)
            right.clicked.connect(cover_layout.itemAt(0).widget().unselected)
        left.clicked.connect(self._prev)
        right.clicked.connect(self._next)

    def _init_cover_layout(self):
        self._cover_layouts = []
        for i in range(N_QUERY):
            cover = searched_cover_widget()
            resolution_label = QLabel()

            layout = QVBoxLayout()
            layout.addWidget(cover, alignment=Qt.AlignCenter)
            layout.addWidget(resolution_label, alignment=Qt.AlignCenter)
            layout.setContentsMargins(0, 0, 0, 0)

            self._cover_layouts.append(layout)

        for i in range(len(self._cover_layouts)):
            self._cover_layouts[i].itemAt(0).widget().clicked.connect(
                lambda x=i: self._set_selected_cover_index(x))
            for j in range(len(self._cover_layouts)):
                if i == j:
                    continue

                self._cover_layouts[i].itemAt(0).widget().clicked.connect(
                    self._cover_layouts[j].itemAt(0).widget().unselected)

    def _init_button_layout(self):
        self._button_layout = QHBoxLayout()
        self._button_layout.setContentsMargins(0, 0, 30, 0)
        self._button_layout.addStretch(1)
        ok_button = QPushButton('OK')
        ok_button.setStyleSheet(self._button_style)
        cancel_button = QPushButton('Cancel')
        cancel_button.setStyleSheet(self._button_style)
        self._button_layout.addWidget(ok_button)
        self._button_layout.addWidget(cancel_button)

        ok_button.clicked.connect(self._ok)
        cancel_button.clicked.connect(self._cancel)

    def _set_state_loading(self):
        for cover_layout in self._cover_layouts:
            cover_layout.itemAt(0).widget().setPixmap(QPixmap())
        center_index = N_QUERY // 2
        self._cover_layouts[center_index].itemAt(0).widget().setText(
            'Loading...')

    def search(self):
        pixmaps = download_cover_images(self._artist_name, self._album_name,
                                        self._cover_start_index, N_QUERY)
        for p in pixmaps:
            resolution = p.size()
            self._cover_pixmaps.append(p)
            self._cover_resolutions.append(resolution)

        self._set_state_showing()

    def _set_state_showing(self):
        for i in range(len(self._cover_layouts)):
            pixmap_index = i + self._cover_start_index - 1
            self._cover_layouts[i].itemAt(0).widget().setPixmap(
                self._cover_pixmaps[pixmap_index])
            width = self._cover_resolutions[pixmap_index].width()
            height = self._cover_resolutions[pixmap_index].height()
            self._cover_layouts[i].itemAt(1).widget().setText('{}x{}'.format(
                width, height))

    def _show_selected_cover(self):
        for i, cover_layout in enumerate(self._cover_layouts):
            if (self._cover_start_index + i) == self._selected_cover_index:
                cover_layout.itemAt(0).widget().selected()

    @pyqtSlot()
    def _set_selected_cover_index(self, cover_layout_index):
        self._selected_cover_index = self._cover_start_index + cover_layout_index - 1

    @pyqtSlot()
    def _prev(self):
        self._cover_start_index = max(1, self._cover_start_index - N_QUERY)
        if self._cover_start_index == 1:
            self._search_layout.itemAt(0).widget().setIcon(
                self._left_dummy_icon)

        self._set_state_showing()
        self._show_selected_cover()

    @pyqtSlot()
    def _next(self):
        self._cover_start_index += N_QUERY
        if self._cover_start_index > len(self._cover_pixmaps):
            self._set_state_loading()
            self.search()
        else:
            self._set_state_showing()
        self._search_layout.itemAt(0).widget().setIcon(self._left_icon)
        self._show_selected_cover()

    @pyqtSlot()
    def _ok(self):
        if self._selected_cover_index != -1:
            self.result.emit(self._cover_pixmaps[self._selected_cover_index])
            self.finished.emit()
            self.close()

    @pyqtSlot()
    def _cancel(self):
        self.canceled.emit()
        self.close()
示例#15
0
class Ui_Widget(object):
    """ Klasa definiująca GUI """
    def setupUi(self, Widget):

        # widgety rysujące kształty, instancje klasy Ksztalt
        self.ksztalt1 = Ksztalt(self, Ksztalty.Polygon)
        self.ksztalt2 = Ksztalt(self, Ksztalty.Ellipse)
        self.ksztaltAktywny = self.ksztalt1

        # przyciski CheckBox ###
        uklad = QVBoxLayout()  # układ pionowy
        self.grupaChk = QButtonGroup()
        for i, v in enumerate(('Kwadrat', 'Koło', 'Trójkąt', 'Linia')):
            self.chk = QCheckBox(v)
            self.grupaChk.addButton(self.chk, i)
            uklad.addWidget(self.chk)
        self.grupaChk.buttons()[self.ksztaltAktywny.ksztalt].setChecked(True)
        # CheckBox do wyboru aktywnego kształtu
        self.ksztaltChk = QCheckBox('<=')
        self.ksztaltChk.setChecked(True)
        uklad.addWidget(self.ksztaltChk)

        # układ poziomy dla kształtów oraz przycisków CheckBox
        ukladH1 = QHBoxLayout()
        ukladH1.addWidget(self.ksztalt1)
        ukladH1.addLayout(uklad)
        ukladH1.addWidget(self.ksztalt2)
        # koniec CheckBox ###

        # Slider i LCDNumber ###
        self.suwak = QSlider(Qt.Horizontal)
        self.suwak.setMinimum(0)
        self.suwak.setMaximum(255)
        self.lcd = QLCDNumber()
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        # układ poziomy (splitter) dla slajdera i lcd
        ukladH2 = QSplitter(Qt.Horizontal, self)
        ukladH2.addWidget(self.suwak)
        ukladH2.addWidget(self.lcd)
        ukladH2.setSizes((125, 75))

        # przyciski RadioButton ###
        self.ukladR = QHBoxLayout()
        for v in ('R', 'G', 'B'):
            self.radio = QRadioButton(v)
            self.ukladR.addWidget(self.radio)
        self.ukladR.itemAt(0).widget().setChecked(True)
        # grupujemy przyciski
        self.grupaRBtn = QGroupBox('Opcje RGB')
        self.grupaRBtn.setLayout(self.ukladR)
        self.grupaRBtn.setObjectName('Radio')
        self.grupaRBtn.setCheckable(True)
        # układ poziomy dla grupy Radio
        ukladH3 = QHBoxLayout()
        ukladH3.addWidget(self.grupaRBtn)
        # koniec RadioButton ###

        # główny układ okna, pionowy ###
        ukladOkna = QVBoxLayout()
        ukladOkna.addLayout(ukladH1)
        ukladOkna.addWidget(ukladH2)
        ukladOkna.addLayout(ukladH3)

        self.setLayout(ukladOkna)  # przypisanie układu do okna głównego
        self.setWindowTitle('Widżety')
示例#16
0
class TableDialog(QDialog):
    def __init__(self, parent, path, datemode):
        super().__init__(parent,
                         Qt.WindowCloseButtonHint | Qt.WindowSystemMenuHint)

        self.path = path
        self.datemode = datemode

        self.setWindowTitle(self.tr("Select columns"))

        self.hlayout = QHBoxLayout()

        buttonBox = QDialogButtonBox(Qt.Horizontal)
        buttonBox.addButton(QDialogButtonBox.Ok)
        buttonBox.accepted.connect(self.accept)

        self.table = QTableWidget(self)
        self.table.setEditTriggers(QTableWidget.NoEditTriggers)

        layout = QVBoxLayout()
        layout.addLayout(self.hlayout)
        layout.addWidget(self.table)
        layout.addWidget(buttonBox)

        self.setLayout(layout)

    def comboChanged(self, _index):
        labels = []
        for i in range(1, self.hlayout.count()):
            combo = self.hlayout.itemAt(i).widget()
            labels.append(combo.currentText())
        self.table.setHorizontalHeaderLabels(labels)

        for i in range(1, self.hlayout.count()):
            combo = self.hlayout.itemAt(i).widget()
            field = combo.currentData()
            if not field:
                continue

            if field.type == Type.Date:
                for row in range(self.table.rowCount()):
                    item = self.table.item(row, i - 1)
                    val = item.text()
                    try:
                        y, m, d, _h, _m, _s = xlrd.xldate_as_tuple(
                            float(val), self.datemode)
                        date = "%d-%02d-%02d" % (y, m, d)
                        item.setText(date)
                    except ValueError:
                        pass
            elif field.type in Type.ImageTypes:
                for row in range(self.table.rowCount()):
                    item = self.table.item(row, i - 1)
                    fileName = item.text()
                    image = QImage()
                    if fileName.startswith('http'):
                        try:
                            # Wikipedia require any header
                            req = urllib.request.Request(
                                fileName,
                                headers={'User-Agent': version.AppName})
                            data = urllib.request.urlopen(req).read()
                            result = image.loadFromData(data)
                            if result:
                                pixmap = QPixmap.fromImage(image)
                                item.setData(Qt.DecorationRole, pixmap)
                        except:
                            pass
                    else:
                        if not os.path.isabs(fileName):
                            fileName = os.path.join(self.path, fileName)

                        result = image.load(fileName)
                        if result:
                            pixmap = QPixmap.fromImage(image)
                            item.setData(Qt.DecorationRole, pixmap)
示例#17
0
class ParameterContainer(QWidget, object):
    """Container to hold Parameter Widgets."""

    def __init__(
            self,
            parameters=None,
            description_text='',
            extra_parameters=None,
            parent=None,
            vertical=True):
        """Constructor

        .. versionadded:: 2.2

        :param parameters: List of Parameter Widget
        :type parameters: list

        :param description_text: Text for description of the parameter
            container.
        :type description_text: str

        """
        super().__init__(parent)
        # attributes
        if not parameters:
            self.parameters = []
        else:
            self.parameters = parameters
        self.description_text = description_text
        self.extra_parameters = extra_parameters
        self.parent = parent
        self.validators = []
        self.validators_kwargs = []

        # UI
        if vertical:
            self.vertical_layout = QVBoxLayout()
        else:
            self.vertical_layout = QHBoxLayout()
        self.widget = QWidget()
        self.description_label = QLabel()
        self.description_label.setWordWrap(True)
        self.scroll_area = QScrollArea()
        self.group_frame = QFrame()
        self.qt5_parameter_factory = Qt5ParameterFactory()
        self.main_layout = QGridLayout()

# NOTES(IS) : These functions are commented since the architecture is not
    #  ready yet.
    # def register_widget(self, parameter, parameter_widget):
    #     """Register new custom widget.
    #
    #     :param parameter:
    #     :type parameter: GenericParameter
    #
    #     :param parameter_widget:
    #     :type parameter_widget: GenericParameterWidget
    #     """
    #     self.qt5_parameter_factory.register_widget(
    # parameter, parameter_widget)
    #
    # def remove_widget(self, parameter):
    #     """Register new custom widget.
    #
    #     :param parameter:
    #     :type parameter: GenericParameter
    #     """
    #     if parameter.__name__ in self.dict_widget.keys():
    #         self.dict_widget.pop(parameter.__name__)

    def get_parameters(self, validate=True):
        """Return list of parameters from the current state of widget.

        :param validate: If true, run validator, else no.
        :type validate: bool

        :returns: List of parameter
        :rtype: list
        """
        if validate:
            validation_result = self.validate()
            if not validation_result['valid']:
                raise InvalidValidationException(validation_result['message'])

        parameter_widgets = self.get_parameter_widgets()

        parameters = []

        for widget_item in parameter_widgets:
            parameter_widget = widget_item.widget()

            parameter = parameter_widget.get_parameter()
            parameters.append(parameter)

        # returns based on the object type of self.parameters
        if isinstance(self.parameters, list):
            return parameters
        else:
            # just return single parameter
            return parameters[0]

    def get_parameter_widgets(self):
        """Return list of parameter widgets from the current state of widget.

        :returns: List of parameter widget
        :rtype: list
        """

        parameter_widgets = [self.vertical_layout.itemAt(i) for i in range(
            self.vertical_layout.count())]

        return parameter_widgets

    def setup_ui(self, must_scroll=True):
        """Setup the UI of this parameter container.
        """
        # Vertical layout to place the parameter widgets
        self.vertical_layout.setContentsMargins(0, 0, 0, 0)
        self.vertical_layout.setSpacing(0)

        # Widget to hold the vertical layout
        self.widget = QWidget()
        self.widget.setLayout(self.vertical_layout)

        # Label for description
        self.description_label.setText(self.description_text)

        self.group_frame.setLineWidth(0)
        self.group_frame.setFrameStyle(QFrame.NoFrame)
        vlayout = QVBoxLayout()
        vlayout.setContentsMargins(0, 0, 0, 0)
        vlayout.setSpacing(0)
        self.group_frame.setLayout(vlayout)

        if must_scroll:
            vlayout.addWidget(self.scroll_area)
            self.scroll_area.setWidgetResizable(True)
            self.scroll_area.setWidget(self.widget)
        else:
            vlayout.addWidget(self.widget)

        # Main layout of the container
        if self.description_text:
            self.main_layout.addWidget(self.description_label)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.main_layout)

        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding)

        if not isinstance(self.parameters, list):
            parameters = [self.parameters]
        else:
            parameters = self.parameters

        if len(parameters) == 0:
            self.set_empty_parameters()
            return

        self.main_layout.addWidget(self.group_frame)

        self.qt5_parameter_factory = Qt5ParameterFactory()
        if self.extra_parameters is not None:
            for extra_parameter in self.extra_parameters:
                if (type(extra_parameter) == tuple and
                        len(extra_parameter) == 2):
                    self.qt5_parameter_factory.register_widget(
                        extra_parameter[0], extra_parameter[1])

        for parameter in parameters:
            parameter_widget = self.qt5_parameter_factory.get_widget(parameter)
            parameter_widget.setAutoFillBackground(True)
            self.vertical_layout.addWidget(parameter_widget)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    def set_description(self, description):
        """Set description of the parameter container.

        :param description: A new description fot the parameter container.
        :type description: str
        """
        self.description_text = description
        self.description_label.setText(self.description_text)

    def set_empty_parameters(self):
        """Update UI if there is no parameters in the container.
        """
        new_description = self.description_text
        new_description += '\n'
        new_description += 'But, currently there is no parameters available.'
        self.description_label.setText(new_description)

    def add_validator(self, validator, **kwargs):
        """Add validator for this parameter container.

        :param validator: validator function for this parameter container.
        :type validator: function
        """
        validator.parent = self
        self.validators.append(validator)
        if kwargs:
            self.validators_kwargs.append(kwargs)
        else:
            self.validators_kwargs.append({})

    def validate(self):
        """Validate of all rule for all parameter in this container.

        :return: True if all valid, False
        :rtype: dict
        """
        for i in range(len(self.validators)):
            validator = self.validators[i]
            validator_kwargs = self.validators_kwargs[i]
            validation_result = validator(self, **validator_kwargs)
            if not validation_result['valid']:
                return validation_result

        return {
            'valid': True,
            'message': ''
        }

    def get_parameter_by_guid(self, parameter_guid):
        """Return a parameter based on its uuid

        :param parameter_guid: The parameter uuid
        :type parameter_guid: str

        :returns: The parameter or None if not exist
        :rtype: GenericParameter, None
        """
        parameters = self.get_parameters(validate=False)
        for parameter in parameters:
            if parameter.guid == parameter_guid:
                return parameter
        return None

    def get_parameter_widget_by_guid(self, parameter_guid):
        """Return a parameter widget based on its uuid

        :param parameter_guid: The parameter uuid
        :type parameter_guid: str

        :returns: The parameter widget or None if not exist
        :rtype: GenericParameterWidget, None
        """
        parameter_widgets = self.get_parameter_widgets()
        for parameter_widget in parameter_widgets:
            if (parameter_widget.widget().get_parameter().guid ==
                    parameter_guid):
                return parameter_widget.widget()
        return None
示例#18
0
class TaskGeneratorDialog(QDialog):
    def __init__(self, nbprocessors):
        QDialog.__init__(self)
        self.layout = QVBoxLayout(self)
        self.taskset = None

        # Utilizations:
        vbox_utilizations = QVBoxLayout()
        group = QGroupBox("Task Utilizations:")

        hbox = QHBoxLayout()
        hbox.addWidget(QLabel("Generator:", self))
        self.comboGenerator = QComboBox()
        self.comboGenerator.addItem("RandFixedSum")
        self.comboGenerator.addItem("UUniFast-Discard")
        self.comboGenerator.addItem("Kato's method")
        self.comboGenerator.currentIndexChanged.connect(self.generator_changed)
        hbox.addWidget(self.comboGenerator)
        vbox_utilizations.addLayout(hbox)

        # Load slider + spinner:
        hbox_load = QHBoxLayout()
        sld = _DoubleSlider(QtCore.Qt.Horizontal, self)
        sld.setMinimum(0)
        sld.setMaximum(32)
        self.spin_load = QDoubleSpinBox(self)
        self.spin_load.setMinimum(0)
        self.spin_load.setMaximum(32)
        self.spin_load.setSingleStep(0.1)
        hbox_load.addWidget(QLabel("Total utilization: ", self))
        hbox_load.addWidget(sld)
        hbox_load.addWidget(self.spin_load)
        sld.doubleValueChanged.connect(self.spin_load.setValue)
        self.spin_load.valueChanged.connect(sld.setValue)
        self.spin_load.setValue(nbprocessors / 2.)
        vbox_utilizations.addLayout(hbox_load)

        # Number of periodic tasks:
        self.hbox_tasks = QHBoxLayout()
        self.spin_tasks = QSpinBox(self)
        self.spin_tasks.setMinimum(0)
        self.spin_tasks.setMaximum(999)  # That's arbitrary.
        self.hbox_tasks.addWidget(QLabel("Number of periodic tasks: ", self))
        self.hbox_tasks.addStretch(1)
        self.hbox_tasks.addWidget(self.spin_tasks)
        vbox_utilizations.addLayout(self.hbox_tasks)

        # Number of sporadic tasks:
        self.hbox_sporadic_tasks = QHBoxLayout()
        self.spin_sporadic_tasks = QSpinBox(self)
        self.spin_sporadic_tasks.setMinimum(0)
        self.spin_sporadic_tasks.setMaximum(999)  # That's arbitrary.
        self.hbox_sporadic_tasks.addWidget(
            QLabel("Number of sporadic tasks: ", self))
        self.hbox_sporadic_tasks.addStretch(1)
        self.hbox_sporadic_tasks.addWidget(self.spin_sporadic_tasks)
        vbox_utilizations.addLayout(self.hbox_sporadic_tasks)

        # Min / Max utilizations
        self.hbox_utilizations = QHBoxLayout()
        self.hbox_utilizations.addWidget(QLabel("Min/Max utilizations: ",
                                                self))
        self.interval_utilization = IntervalSpinner(
            self, min_=0, max_=1, step=.01, round_option=False)
        self.hbox_utilizations.addWidget(self.interval_utilization)
        vbox_utilizations.addLayout(self.hbox_utilizations)

        group.setLayout(vbox_utilizations)
        self.layout.addWidget(group)

        # Periods:
        vbox_periods = QVBoxLayout()
        group = QGroupBox("Task Periods:")

        # Log uniform
        self.lunif = QRadioButton("log-uniform distribution between:")
        vbox_periods.addWidget(self.lunif)
        self.lunif.setChecked(True)

        self.lunif_interval = IntervalSpinner(self)
        self.lunif_interval.setEnabled(self.lunif.isChecked())
        self.lunif.toggled.connect(self.lunif_interval.setEnabled)
        vbox_periods.addWidget(self.lunif_interval)

        # Uniform
        self.unif = QRadioButton("uniform distribution between:")
        vbox_periods.addWidget(self.unif)

        self.unif_interval = IntervalSpinner(self)
        self.unif_interval.setEnabled(self.unif.isChecked())
        self.unif.toggled.connect(self.unif_interval.setEnabled)
        vbox_periods.addWidget(self.unif_interval)

        # Discrete
        discrete = QRadioButton("chosen among these (space separated) values:")
        vbox_periods.addWidget(discrete)

        self.periods = QLineEdit(self)
        self.periods.setValidator(QRegExpValidator(
            QRegExp("^\\d*(\.\\d*)?( \\d*(\.\\d*)?)*$")))

        vbox_periods.addWidget(self.periods)
        self.periods.setEnabled(discrete.isChecked())
        discrete.toggled.connect(self.periods.setEnabled)
        vbox_periods.addStretch(1)

        group.setLayout(vbox_periods)
        self.layout.addWidget(group)

        buttonBox = QDialogButtonBox()
        cancel = buttonBox.addButton(QDialogButtonBox.Cancel)
        generate = buttonBox.addButton("Generate", QDialogButtonBox.AcceptRole)
        cancel.clicked.connect(self.reject)
        generate.clicked.connect(self.generate)
        self.layout.addWidget(buttonBox)

        self.show_randfixedsum_options()

    def generator_changed(self, value):
        if value == 2:
            self.show_kato_options()
        else:
            self.show_randfixedsum_options()

    def show_randfixedsum_options(self):
        for i in range(self.hbox_utilizations.count()):
            self.hbox_utilizations.itemAt(i).widget().hide()
        for i in range(self.hbox_tasks.count()):
            if self.hbox_tasks.itemAt(i).widget():
                self.hbox_tasks.itemAt(i).widget().show()
        for i in range(self.hbox_sporadic_tasks.count()):
            if self.hbox_sporadic_tasks.itemAt(i).widget():
                self.hbox_sporadic_tasks.itemAt(i).widget().show()

    def show_kato_options(self):
        for i in range(self.hbox_utilizations.count()):
            if self.hbox_utilizations.itemAt(i).widget():
                self.hbox_utilizations.itemAt(i).widget().show()
        for i in range(self.hbox_tasks.count()):
            if self.hbox_tasks.itemAt(i).widget():
                self.hbox_tasks.itemAt(i).widget().hide()
        for i in range(self.hbox_sporadic_tasks.count()):
            if self.hbox_sporadic_tasks.itemAt(i).widget():
                self.hbox_sporadic_tasks.itemAt(i).widget().hide()

    def get_min_utilization(self):
        return self.interval_utilization.getMin()

    def get_max_utilization(self):
        return self.interval_utilization.getMax()

    def generate(self):

        n = self.get_nb_tasks()
        if (n == 0):
            QMessageBox.warning(
                    self, "Generation failed",
                    "Please check the utilization and the number of tasks.")
            return

        if self.comboGenerator.currentIndex() == 0:
            u = StaffordRandFixedSum(n, self.get_utilization(), 1)
        elif self.comboGenerator.currentIndex() == 1:
            u = UUniFastDiscard(n, self.get_utilization(), 1)
        else:
            u = gen_kato_utilizations(1, self.get_min_utilization(),
                                      self.get_max_utilization(),
                                      self.get_utilization())
            n = len(u[0])

        p_types = self.get_periods()
        if p_types[0] == "unif":
            p = gen_periods_uniform(n, 1, p_types[1], p_types[2], p_types[3])
        elif p_types[0] == "lunif":
            p = gen_periods_loguniform(n, 1, p_types[1], p_types[2],
                                       p_types[3])
        else:
            p = gen_periods_discrete(n, 1, p_types[1])
            
        if u and p:
            self.taskset = gen_tasksets(u, p)[0]
            self.accept()
        elif not u:
            QMessageBox.warning(
                self, "Generation failed",
                "Please check the utilization and the number of tasks.")
        else:
            QMessageBox.warning(
                self, "Generation failed",
                "Pleache check the periods.")

    def get_nb_tasks(self):
        return self.spin_tasks.value() + self.spin_sporadic_tasks.value()

    def get_nb_periodic_tasks(self):
        return self.spin_tasks.value()

    def get_nb_sporadic_tasks(self):
        return self.spin_sporadic_tasks.value()

    def get_utilization(self):
        return self.spin_load.value()

    def get_periods(self):
        if self.unif.isChecked():
            return ("unif", self.unif_interval.getMin(),
                    self.unif_interval.getMax(), self.unif_interval.getRound())
        elif self.lunif.isChecked():
            return ("lunif", self.lunif_interval.getMin(),
                    self.lunif_interval.getMax(),
                    self.lunif_interval.getRound())
        else:
            return ("discrete", map(float, str(self.periods.text()).split()))
示例#19
0
class Ui_Widget(object):
    """ Klasa definiująca GUI """

    def setupUi(self, Widget):

        # widgety rysujące kształty, instancje klasy Ksztalt
        self.ksztalt1 = Ksztalt(self, Ksztalty.Polygon)
        self.ksztalt2 = Ksztalt(self, Ksztalty.Ellipse)
        self.ksztaltAktywny = self.ksztalt1

        # przyciski CheckBox ###
        uklad = QVBoxLayout()  # układ pionowy
        self.grupaChk = QButtonGroup()
        for i, v in enumerate(('Kwadrat', 'Koło', 'Trójkąt', 'Linia')):
            self.chk = QCheckBox(v)
            self.grupaChk.addButton(self.chk, i)
            uklad.addWidget(self.chk)
        self.grupaChk.buttons()[self.ksztaltAktywny.ksztalt].setChecked(True)
        # CheckBox do wyboru aktywnego kształtu
        self.ksztaltChk = QCheckBox('<=')
        self.ksztaltChk.setChecked(True)
        uklad.addWidget(self.ksztaltChk)

        # układ poziomy dla kształtów oraz przycisków CheckBox
        ukladH1 = QHBoxLayout()
        ukladH1.addWidget(self.ksztalt1)
        ukladH1.addLayout(uklad)
        ukladH1.addWidget(self.ksztalt2)
        # koniec CheckBox ###

        # Slider i LCDNumber ###
        self.suwak = QSlider(Qt.Horizontal)
        self.suwak.setMinimum(0)
        self.suwak.setMaximum(255)
        self.lcd = QLCDNumber()
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        # układ poziomy (splitter) dla slajdera i lcd
        ukladH2 = QSplitter(Qt.Horizontal, self)
        ukladH2.addWidget(self.suwak)
        ukladH2.addWidget(self.lcd)
        ukladH2.setSizes((125, 75))

        # przyciski RadioButton ###
        self.ukladR = QHBoxLayout()
        for v in ('R', 'G', 'B'):
            self.radio = QRadioButton(v)
            self.ukladR.addWidget(self.radio)
        self.ukladR.itemAt(0).widget().setChecked(True)
        # grupujemy przyciski
        self.grupaRBtn = QGroupBox('Opcje RGB')
        self.grupaRBtn.setLayout(self.ukladR)
        self.grupaRBtn.setObjectName('Radio')
        self.grupaRBtn.setCheckable(True)
        # układ poziomy dla grupy Radio
        ukladH3 = QHBoxLayout()
        ukladH3.addWidget(self.grupaRBtn)
        # koniec RadioButton ###

        # Lista ComboBox i SpinBox ###
        self.listaRGB = QComboBox(self)
        for v in ('R', 'G', 'B'):
            self.listaRGB.addItem(v)
        self.listaRGB.setEnabled(False)
        # SpinBox
        self.spinRGB = QSpinBox()
        self.spinRGB.setMinimum(0)
        self.spinRGB.setMaximum(255)
        self.spinRGB.setEnabled(False)
        # układ pionowy dla ComboBox i SpinBox
        uklad = QVBoxLayout()
        uklad.addWidget(self.listaRGB)
        uklad.addWidget(self.spinRGB)
        # do układu poziomego grupy Radio dodajemy układ ComboBox i SpinBox
        ukladH3.insertSpacing(1, 25)
        ukladH3.addLayout(uklad)
        # koniec ComboBox i SpinBox ###

        # przyciski PushButton ###
        uklad = QHBoxLayout()
        self.grupaP = QButtonGroup()
        self.grupaP.setExclusive(False)
        for v in ('R', 'G', 'B'):
            self.btn = QPushButton(v)
            self.btn.setCheckable(True)
            self.grupaP.addButton(self.btn)
            uklad.addWidget(self.btn)
        # grupujemy przyciski
        self.grupaPBtn = QGroupBox('Przyciski RGB')
        self.grupaPBtn.setLayout(uklad)
        self.grupaPBtn.setObjectName('Push')
        self.grupaPBtn.setCheckable(True)
        self.grupaPBtn.setChecked(False)
        # koniec PushButton ###

        # główny układ okna, wertykalny ###
        ukladOkna = QVBoxLayout()
        ukladOkna.addLayout(ukladH1)
        ukladOkna.addWidget(ukladH2)
        ukladOkna.addLayout(ukladH3)
        ukladOkna.addWidget(self.grupaPBtn)

        self.setLayout(ukladOkna)  # przypisanie układu do okna głównego
        self.setWindowTitle('Widżety')
示例#20
0
class EstimhabW(StatModUseful):
    """
    The Estimhab class provides the graphical interface for the version of the Estimhab model written in HABBY.
    The Estimhab model is described elsewhere. EstimhabW() just loads the data for Estimhab given by the user.
    """

    save_signal_estimhab = pyqtSignal()
    """
    PyQtsignal to save the Estimhab data.
    """
    def __init__(self, path_prj, name_prj):

        super().__init__()
        self.tab_name = "estimhab"
        self.tab_position = 7
        self.model_type = "Estimhab"
        self.eq50 = QLineEdit()
        self.esub = QLineEdit()
        self.path_prj = path_prj
        self.name_prj = name_prj
        self.path_bio_estimhab = os.path.join(self.path_bio, 'estimhab')
        self.total_lineedit_number = 1
        self.init_iu()
        self.process_manager = MyProcessManager(
            "estimhab_plot")  # SC (Suitability Curve)
        self.read_estimhab_dict()
        self.fill_input_data()
        self.fill_fish_name()
        self.check_if_ready_to_compute()
        self.eq1.textChanged.connect(self.check_if_ready_to_compute)
        self.eq2.textChanged.connect(self.check_if_ready_to_compute)
        self.ew1.textChanged.connect(self.check_if_ready_to_compute)
        self.ew2.textChanged.connect(self.check_if_ready_to_compute)
        self.eh1.textChanged.connect(self.check_if_ready_to_compute)
        self.eh2.textChanged.connect(self.check_if_ready_to_compute)
        self.eq50.textChanged.connect(self.check_if_ready_to_compute)
        self.eqmin.textChanged.connect(self.check_if_ready_to_compute)
        self.eqmax.textChanged.connect(self.check_if_ready_to_compute)
        self.esub.textChanged.connect(self.check_if_ready_to_compute)
        self.selected_aquatic_animal_qtablewidget.model().rowsInserted.connect(
            self.check_if_ready_to_compute)
        self.selected_aquatic_animal_qtablewidget.model().rowsRemoved.connect(
            self.check_if_ready_to_compute)

    def init_iu(self):
        """
        This function is used to initialized an instance of the EstimhabW() class. It is called by __init__().

         **Technical comments and walk-through**

         First we looked if some data for Estimhab was saved before by an user. If yes, we will fill the GUI with
         the information saved before. Estimhab information is saved in hdf5 file format and the path/name of the
         hdf5 file is saved in the xml project file. So we open the xml project file and look if the name of an hdf5
         file was saved for Estimhab. If yes, the hdf5 file is read.

         The format of hdf5 file is relatively simple. Each input data for Estimhab has its own dataset (qmes, hmes,
         wmes, q50, qrange, and substrate).  Then, we have a list of string which are a code for the fish species which
         were analyzed.  All the data contained in hdf5 file is loaded into variable.

         The different label are written on the graphical interface. Then, two QListWidget are modified. The first
         list contains all the fish species on which HABBY has info (see XML Estimhab format for more info).
         The second list is the fish selected by the user on which Estimhab will be run. Here, we link these lists
         with two functions so that the user can select/deselect fish using the mouse. The function name are add_fish()
         and remove_fish().

         Then, we fill the first list. HABBY look up all file of xml type in the “Path_bio” folder (the one indicated in
         the xml project file under the attribute “Path_bio”).  The name are them modified so that the only the name of
         species appears (and not the full path). We set the layout with all the different QLineEdit where the user
         can write the needed data.

         Estimhab model is saved using a function situated in MainWindows_1.py  (frankly, I am not so sure why I did put
         the save function there, but anyway). So the save button just send a signal to MainWindows
         here, which save the data.
        """

        available_model_label = QLabel(self.tr('Available'))
        selected_model_label = QLabel(self.tr('Selected'))

        self.lineedit_width = 50
        self.spacer_width = 50

        # input
        q1_layout = QHBoxLayout()
        q1_layout.addWidget(QLabel('Q1 [m<sup>3</sup>/s]'))
        q1_layout.addWidget(self.eq1)
        q1_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.eq1.setFixedWidth(self.lineedit_width)

        q2_layout = QHBoxLayout()
        q2_layout.addWidget(QLabel('Q2 [m<sup>3</sup>/s]'))
        q2_layout.addWidget(self.eq2)
        q2_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.eq2.setFixedWidth(self.lineedit_width)

        w1_layout = QHBoxLayout()
        w1_layout.addWidget(QLabel(self.tr("Width1 [m]")))
        w1_layout.addWidget(self.ew1)
        w1_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.ew1.setFixedWidth(self.lineedit_width)

        w2_layout = QHBoxLayout()
        w2_layout.addWidget(QLabel(self.tr("Width2 [m]")))
        w2_layout.addWidget(self.ew2)
        w2_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.ew2.setFixedWidth(self.lineedit_width)

        h1_layout = QHBoxLayout()
        h1_layout.addWidget(QLabel(self.tr("Height1 [m]")))
        h1_layout.addWidget(self.eh1)
        self.eh1.setFixedWidth(self.lineedit_width)

        h2_layout = QHBoxLayout()
        h2_layout.addWidget(QLabel(self.tr("Height2 [m]")))
        h2_layout.addWidget(self.eh2)
        self.eh2.setFixedWidth(self.lineedit_width)

        q50_layout = QHBoxLayout()
        q50_layout.addWidget(QLabel('Qmedian/Q50 [m<sup>3</sup>/s]'))
        q50_layout.addWidget(self.eq50)
        q50_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.eq50.setFixedWidth(self.lineedit_width)

        sub_layout = QHBoxLayout()
        sub_layout.addWidget(QLabel(self.tr('Mean substrate size [m]')))
        sub_layout.addWidget(self.esub)
        sub_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.esub.setFixedWidth(self.lineedit_width)

        # output
        q1out_layout = QHBoxLayout()
        q1out_layout.addWidget(QLabel(self.tr("Qmin [m<sup>3</sup>/s]")))
        q1out_layout.addWidget(self.eqmin)
        q1out_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.eqmin.setFixedWidth(self.lineedit_width)

        q2out_layout = QHBoxLayout()
        q2out_layout.addWidget(QLabel(self.tr("Qmax [m<sup>3</sup>/s]")))
        q2out_layout.addWidget(self.eqmax)
        q2out_layout.addItem(QSpacerItem(self.spacer_width, 1))
        self.eqmax.setFixedWidth(self.lineedit_width)

        self.q2target_layout = QHBoxLayout()
        self.q2target_layout.addWidget(
            QLabel(self.tr("Qtarget [m<sup>3</sup>/s]")))
        self.q2target_layout.addWidget(self.add_qtarget_button)
        self.q2target_layout.addWidget(self.remove_qtarget_button)
        self.add_qtarget_button.clicked.connect(self.add_new_qtarget)
        self.remove_qtarget_button.clicked.connect(self.remove_one_qtarget)

        # create lists with the possible fishes
        self.list_f.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list_f.setDragDropMode(QAbstractItemView.DragDrop)
        self.list_f.setDefaultDropAction(Qt.MoveAction)
        self.list_f.setAcceptDrops(True)
        self.list_f.setSortingEnabled(True)

        self.selected_aquatic_animal_qtablewidget.setSelectionMode(
            QAbstractItemView.ExtendedSelection)
        self.selected_aquatic_animal_qtablewidget.setDragDropMode(
            QAbstractItemView.DragDrop)
        self.selected_aquatic_animal_qtablewidget.setDefaultDropAction(
            Qt.MoveAction)
        self.selected_aquatic_animal_qtablewidget.setAcceptDrops(True)
        self.selected_aquatic_animal_qtablewidget.setSortingEnabled(True)

        # insist on white background color (for linux, mac)
        self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.white)
        self.setPalette(p)

        # send model
        self.run_stop_button = QPushButton(self.tr('Run Estimhab'), self)
        self.run_stop_button.clicked.connect(self.run_estmihab)
        change_button_color(self.run_stop_button, "#47B5E6")
        self.run_stop_button.setEnabled(False)

        # empty frame scrolable
        content_widget = QFrame()

        # hydraulic_data_group
        hydraulic_data_group = QGroupBox(self.tr('Hydraulic data input'))
        hydraulic_data_group.setToolTip(
            self.tr("Double click to reset the input data group."))
        hydraulic_data_layout = QGridLayout(hydraulic_data_group)
        hydraulic_data_layout.addLayout(q1_layout, 0, 0)
        hydraulic_data_layout.addLayout(w1_layout, 0, 1)
        hydraulic_data_layout.addLayout(h1_layout, 0, 2)
        hydraulic_data_layout.addLayout(q2_layout, 1, 0)
        hydraulic_data_layout.addLayout(w2_layout, 1, 1)
        hydraulic_data_layout.addLayout(h2_layout, 1, 2)
        hydraulic_data_layout.addLayout(q50_layout, 2, 0)
        hydraulic_data_layout.addLayout(sub_layout, 2, 1)
        hydraulic_data_group.setSizePolicy(QSizePolicy.Maximum,
                                           QSizePolicy.Maximum)
        self.doubleclick_input_group = DoubleClicOutputGroup()
        hydraulic_data_group.installEventFilter(self.doubleclick_input_group)
        self.doubleclick_input_group.double_clic_signal.connect(
            self.reset_hydraulic_data_input_group)

        # hydraulic_data_output_group
        hydraulic_data_output_group = QGroupBox(
            self.tr('Desired hydraulic output data'))
        hydraulic_data_output_group.setToolTip(
            self.tr("Double click to reset the outpout data group."))
        hydraulic_data_layout = QGridLayout(hydraulic_data_output_group)
        hydraulic_data_layout.addLayout(q1out_layout, 0, 0)
        hydraulic_data_layout.addLayout(q2out_layout, 0, 1)
        hydraulic_data_layout.addLayout(self.q2target_layout, 0, 2)
        hydraulic_data_output_group.setSizePolicy(QSizePolicy.Maximum,
                                                  QSizePolicy.Maximum)
        self.doubleclick_output_group = DoubleClicOutputGroup()
        hydraulic_data_output_group.installEventFilter(
            self.doubleclick_output_group)
        self.doubleclick_output_group.double_clic_signal.connect(
            self.reset_hydraulic_data_output_group)

        # models_group
        models_group = QGroupBox(self.tr('Biological models'))
        models_layout = QGridLayout(models_group)
        models_layout.addWidget(available_model_label, 0, 0)
        models_layout.addWidget(selected_model_label, 0, 1)
        models_layout.addWidget(self.list_f, 1, 0)
        models_layout.addWidget(self.selected_aquatic_animal_qtablewidget, 1,
                                1)
        models_layout.addWidget(self.run_stop_button, 2, 1)
        self.doubleclick_models_group = DoubleClicOutputGroup()
        models_group.installEventFilter(self.doubleclick_models_group)
        self.doubleclick_models_group.double_clic_signal.connect(
            self.reset_models_group)

        # gereral_layout
        self.layout3 = QVBoxLayout(content_widget)
        self.layout3.addWidget(hydraulic_data_group, Qt.AlignLeft)
        self.layout3.addWidget(hydraulic_data_output_group)
        self.layout3.addWidget(models_group)

        # self.setLayout(self.layout3)
        self.setWidgetResizable(True)
        self.setFrameShape(QFrame.NoFrame)
        self.setWidget(content_widget)

    def add_new_qtarget(self):
        # count existing number of lineedit
        total_widget_number = self.q2target_layout.count()
        self.total_lineedit_number = total_widget_number - 2  # - first : qlabel and plus and moins button + New lineedit
        lineedit_name = 'new_qtarget' + str(self.total_lineedit_number)
        setattr(self, lineedit_name, QLineEdit())
        getattr(self, lineedit_name).setFixedWidth(self.lineedit_width)
        self.target_lineedit_list.append(getattr(self, lineedit_name))
        self.q2target_layout.insertWidget(total_widget_number - 2,
                                          getattr(self, lineedit_name))

    def remove_one_qtarget(self):
        # count existing number of lineedit
        total_widget_number = self.q2target_layout.count()
        self.total_lineedit_number = total_widget_number - 3  # - first : qlabel and plus and moins button - New lineedit
        if self.total_lineedit_number > 0:
            self.target_lineedit_list.pop(-1)
            self.q2target_layout.itemAt(total_widget_number -
                                        3).widget().setParent(None)
            self.total_lineedit_number = self.total_lineedit_number - 1

    def reset_hydraulic_data_input_group(self):
        # remove txt in lineedit
        self.eq1.setText("")
        self.eq2.setText("")
        self.ew1.setText("")
        self.ew2.setText("")
        self.eh1.setText("")
        self.eh2.setText("")
        self.eq50.setText("")
        self.esub.setText("")

    def reset_hydraulic_data_output_group(self):
        # remove txt in lineedit
        self.eqmin.setText("")
        self.eqmax.setText("")
        # remove lineedits qtarget
        for i in reversed(range(1, self.q2target_layout.count() - 1)):
            self.q2target_layout.itemAt(i).widget().setParent(None)
            self.total_lineedit_number = self.total_lineedit_number - 1
        self.target_lineedit_list = []

    def reset_models_group(self):
        if self.selected_aquatic_animal_qtablewidget.count() > 0:
            self.selected_aquatic_animal_qtablewidget.clear()
            self.fill_fish_name()

    def read_estimhab_dict(self):
        """
        This function opens the json data created by estimhab
        """
        # load_project_properties
        self.estimhab_dict = load_specific_properties(self.path_prj,
                                                      [self.model_type])[0]

    def fill_fish_name(self):
        """
        This function reads all latin fish name from the xml files which are contained in the biological directory
        related to estimhab and fill GUI fish names
        """
        all_xmlfile = glob.glob(os.path.join(self.path_bio_estimhab, r'*.xml'))

        if self.estimhab_dict:
            selected_fish = self.estimhab_dict["fish_list"]
        else:
            selected_fish = []

        for f in all_xmlfile:
            # open xml
            try:
                try:
                    docxml = ET.parse(f)
                    root = docxml.getroot()
                except IOError:
                    self.send_log.emit(
                        self.tr("Warning: ") +
                        self.tr("The .habby project file ") + f +
                        self.tr(" could not be open.\n"))
                    return
            except ET.ParseError:
                self.send_log.emit(
                    self.tr("Warning: ") +
                    self.tr("The .habby project file ") + f +
                    self.tr(" is not well-formed.\n"))
                return

            # find fish name
            fish_name = root.find(".//LatinName")
            # None is null for python 3
            if fish_name is not None:
                fish_name = fish_name.text.strip()

            # find fish stage
            stage = root.find(".//estimhab/stage")
            # None is null for python 3
            if stage is not None:
                stage = stage.text.strip()
            if stage != 'all_stage':
                fish_name += ' ' + stage

            # check if not selected
            if fish_name not in selected_fish:
                # add to the list
                item = QListWidgetItem(fish_name)
                item.setData(1, f)
                self.list_f.addItem(item)
            else:
                # add to the list
                item2 = QListWidgetItem(fish_name)
                item2.setData(1, f)
                self.selected_aquatic_animal_qtablewidget.addItem(item2)

    def fill_input_data(self):
        if self.estimhab_dict:
            # input data
            self.eq1.setText(str(self.estimhab_dict["q"][0]))
            self.eq2.setText(str(self.estimhab_dict["q"][1]))
            self.eh1.setText(str(self.estimhab_dict["h"][0]))
            self.eh2.setText(str(self.estimhab_dict["h"][1]))
            self.ew1.setText(str(self.estimhab_dict["w"][0]))
            self.ew2.setText(str(self.estimhab_dict["w"][1]))
            self.eq50.setText(str(self.estimhab_dict["q50"]))
            self.eqmin.setText(str(self.estimhab_dict["qrange"][0]))
            self.eqmax.setText(str(self.estimhab_dict["qrange"][1]))
            self.esub.setText(str(self.estimhab_dict["substrate"]))
            # qtarg
            if len(self.estimhab_dict["qtarg"]) > 0:
                while self.total_lineedit_number != len(
                        self.estimhab_dict["qtarg"]):
                    self.add_new_qtarget()
                for qtarg_num, qtarg_value in enumerate(
                        self.estimhab_dict["qtarg"][1:]):
                    getattr(self, 'new_qtarget' + str(qtarg_num + 2)).setText(
                        str(qtarg_value))

    def check_if_ready_to_compute(self):
        all_string_selection = (self.eq1.text(), self.eq2.text(),
                                self.ew1.text(), self.ew2.text(),
                                self.eh1.text(), self.eh2.text(),
                                self.eq50.text(), self.eqmin.text(),
                                self.eqmax.text(), self.esub.text())
        # minimum one fish and string in input lineedits to enable run_stop_button
        if self.selected_aquatic_animal_qtablewidget.count(
        ) > 0 and "" not in all_string_selection:
            self.run_stop_button.setEnabled(True)
        else:
            self.run_stop_button.setEnabled(False)

    def change_folder(self):
        """
        A small method to change the folder which indicates where is the biological data
        """
        # user find new path
        self.path_bio_estimhab = QFileDialog.getExistingDirectory(
            self, self.tr("Open Directory"), os.getenv('HOME'))
        # update list
        self.list_f.clear()
        all_file = glob.glob(os.path.join(self.path_bio_estimhab, r'*.xml'))
        # make it look nicer
        for i in range(0, len(all_file)):
            all_file[i] = all_file[i].replace(self.path_bio_estimhab, "")
            all_file[i] = all_file[i].replace("\\", "")
            all_file[i] = all_file[i].replace(".xml", "")
            item = QListWidgetItem(all_file[i])
            # add them to the menu
            self.list_f.addItem(item)

    def run_estmihab(self):
        """
        A function to execute Estimhab by calling the estimhab function.

        **Technical comment**

        This is the function making the link between the GUI and the source code proper. The source code for Estimhab
        is in src/Estimhab.py.

        This function loads in memory the data given in the graphical interface and call sthe Estimhab model.
        The data could be written by the user now or it could be data which was saved in the hdf5 file before and
        loaded when HABBY was open (and the init function called).  We check that all necessary data is present and
        that the data given makes sense (e.g.,the minimum discharge should not be bigger than the maximal discharge,
        the data should be a float, etc.). We then remove the duplicate fish species (in case the user select one
        specie twice) and the Estimhab model is called. The log is then written (see the paragraph on the log for more
        information). Next, the figures created by Estimmhab are shown. As there is only a short number of outputs
        for Estimhab, we create a figure in all cases (it could be changed by adding a checkbox on the GUI like
        in the Telemac or other hydrological class).

        """
        # prepare data
        try:
            q = [
                float(self.eq1.text().replace(",", ".")),
                float(self.eq2.text().replace(",", "."))
            ]
            w = [
                float(self.ew1.text().replace(",", ".")),
                float(self.ew2.text().replace(",", "."))
            ]
            h = [
                float(self.eh1.text().replace(",", ".")),
                float(self.eh2.text().replace(",", "."))
            ]
            q50 = float(self.eq50.text().replace(",", "."))
            qrange = [
                float(self.eqmin.text().replace(",", ".")),
                float(self.eqmax.text().replace(",", "."))
            ]
            qtarget_values_list = []
            for qtarg_lineedit in self.target_lineedit_list:
                if qtarg_lineedit.text():
                    qtarget_values_list.append(
                        float(qtarg_lineedit.text().replace(",", ".")))
            substrate = float(self.esub.text().replace(",", "."))
        except ValueError:
            self.send_log.emit('Error: ' + self.tr(
                'Some data are empty or not float. Cannot run Estimhab'))
            return

        # get the list of xml file
        fish_list = []
        fish_name2 = []
        for i in range(0, self.selected_aquatic_animal_qtablewidget.count()):
            fish_item = self.selected_aquatic_animal_qtablewidget.item(i)
            fish_item_str = fish_item.text()
            fish_list.append(os.path.basename(fish_item.data(1)))
            fish_name2.append(fish_item_str)
        # check internal logic
        if not fish_list:
            self.send_log.emit(
                'Error: ' + self.tr('No fish selected. Cannot run Estimhab.'))
            return
        if qrange[0] >= qrange[1]:
            self.send_log.emit('Error: ' + self.tr(
                'Minimum discharge bigger or equal to max discharge. Cannot run Estimhab.'
            ))
            return
        if qtarget_values_list:
            for qtarg in qtarget_values_list:
                if qtarg < qrange[0] or qtarg > qrange[1]:
                    self.send_log.emit('Error: ' + self.tr(
                        'Target discharge is not between Qmin and Qmax. Cannot run Estimhab.'
                    ))
                    return
        if q[0] == q[1]:
            self.send_log.emit(
                'Error: ' +
                self.tr('Estimhab needs two differents measured discharges.'))
            return
        if h[0] == h[1]:
            self.send_log.emit(
                'Error: ' +
                self.tr('Estimhab needs two different measured height.'))
            return
        if w[0] == w[1]:
            self.send_log.emit(
                'Error: ' +
                self.tr('Estimhab needs two different measured width.'))
            return
        if (q[0] > q[1] and h[0] < h[1]) or (q[0] > q[1] and w[0] < w[1]) or (q[1] > q[0] and h[1] < h[0]) \
                or (q[1] > q[0] and w[1] < w[0]):
            self.send_log.emit(
                'Error: ' +
                self.tr('Discharge, width, and height data are not coherent.'))
            return
        if q[0] <= 0 or q[1] <= 0 or w[0] <= 0 or w[1] <= 0 or h[0] <= 0 or h[1] <= 0 or qrange[0] <= 0 or qrange[1] <= 0 \
                or substrate <= 0 or q50 <= 0:
            self.send_log.emit('Error: ' + self.tr(
                'Negative or zero data found. Could not run Estimhab.'))
            return
        if substrate > 3:
            self.send_log.emit(
                'Error: ' +
                self.tr('Substrate is too large. Could not run Estimhab.'))
            return

        self.send_log.emit(self.tr('# Computing: Estimhab...'))

        # check if the discharge range is realistic with the result
        self.qall = [q[0], q[1], qrange[0], qrange[1], q50]
        self.check_all_q()

        # run and save
        project_properties = load_project_properties(self.path_prj)
        sys.stdout = mystdout = StringIO()

        self.estimhab_dict = dict(q=q,
                                  w=w,
                                  h=h,
                                  q50=q50,
                                  qrange=qrange,
                                  qtarg=qtarget_values_list,
                                  substrate=substrate,
                                  path_bio=self.path_bio_estimhab,
                                  xml_list=fish_list,
                                  fish_list=fish_name2)

        # change_specific_properties
        change_specific_properties(self.path_prj, ["Estimhab"],
                                   [self.estimhab_dict])

        # process
        state = Value("d", 0)
        self.p = Process(target=estimhab_mod.estimhab_process,
                         args=(self.estimhab_dict, project_properties,
                               self.path_prj, state),
                         name="Estimhab")
        self.p.start()
        self.p.join()

        # plot
        plot_attr = lambda: None
        plot_attr.name_hdf5 = self.name_prj + '_ESTIMHAB' + '.hab'
        plot_attr.nb_plot = 1

        self.process_manager.set_estimhab_plot_mode(
            self.path_prj, plot_attr, load_project_properties(self.path_prj))
        self.process_manager.start()

        # log info
        str_found = mystdout.getvalue()
        str_found = str_found.split('\n')
        for i in range(0, len(str_found)):
            if len(str_found[i]) > 1:
                self.send_log.emit(str_found[i])

        self.send_log.emit(
            self.
            tr("Estimhab computation done. Figure and text files created in output project folder."
               ))
        self.send_log.emit("py    data = [" + str(q) + ',' + str(w) + ',' +
                           str(h) + ',' + str(q50) + ',' + str(substrate) +
                           ']')
        self.send_log.emit("py    qrange =[" + str(qrange[0]) + ',' +
                           str(qrange[1]) + ']')
        self.send_log.emit(
            "py    path1= os.path.join(os.path.dirname(path_bio),'" +
            self.path_bio_estimhab + "')")
        fish_list_str = "py    fish_list = ["
        for i in range(0, len(fish_list)):
            fish_list_str += "'" + fish_list[i] + "',"
        fish_list_str = fish_list_str[:-1] + ']'
        self.send_log.emit(fish_list_str)
        self.send_log.emit(
            "py    [OSI, WUA] = estimhab.estimhab(data[0], data[1], data[2], data[3] ,"
            " qrange, data[4], path1, fish_list, '.', True, {}, '.')\n")
class ColorChangeHue(QMainWindow):
    def __init__(self, parent_win, dom_colors):
        super().__init__()
        self.title = 'Interactively change the color by hue matching'
        self.left = 50
        self.top = 50
        self.width = 480
        self.height = 150
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.wid = QWidget(self)
        self.setCentralWidget(self.wid)
        self.mainlayout = QVBoxLayout()
        self.wid.setLayout(self.mainlayout)
        print(dom_colors)
        self.h_dom_colors = []
        for dc in dom_colors:
            self.h_dom_colors.append(
                transfer_lab.rgb2hue_opencv(transfer_lab.lab2rgb_opencv(dc))[0]
                * 2)
        self.parent_win = parent_win
        self.add_hue_matchings()
        self.source_hue_idx = None
        self.target_hue_idx = None
        self.src_tar_mp = {}

        self.setStyleSheet(
            "QLabel{background:white;}"
            "QLabel{color:rgb(100,100,100,250);font-size:15px;font-weight:bold;font-family:Roman times;}"
            "QLabel:hover{color:rgb(100,100,100,120);}")

    def add_hue_matchings(self):
        self.top_hue_layout = QHBoxLayout()
        self.mid_hue_layout = QHBoxLayout()
        self.bottom_hue_layout = QHBoxLayout()
        self.mainlayout.addLayout(self.top_hue_layout)
        self.mainlayout.addLayout(self.mid_hue_layout)
        self.mainlayout.addLayout(self.bottom_hue_layout)
        bin_size = 10
        self.binsz = bin_size
        for idx, w in enumerate(range(0, 360, bin_size)):
            mid_h = int((idx + 0.5) * bin_size)
            if mid_h >= 360:
                break
            q = QLabel()
            q.setAutoFillBackground(True)
            q.setText("  ")

            q.setMargin(5)
            p = q.palette()
            ss = False
            for hu_range in range(int(mid_h - bin_size * 0.5),
                                  int(mid_h + bin_size * 0.5)):
                if hu_range in self.h_dom_colors:
                    ss = True
            if ss:
                # p.setColor(q.backgroundRole(),QColor.fromHsl(mid_h,255,128))
                q.setStyleSheet("background-color: %s" %
                                (QColor.fromHsl(mid_h, 255, 128).name()))
            else:
                # p.setColor(q.backgroundRole(), QColor.fromHsl(mid_h, 255, 128,alpha=0))
                q.setStyleSheet("background-color: %s" % (QColor.fromHsl(
                    mid_h, 255, 128, alpha=0).name(QColor.HexArgb)))
            q.setPalette(p)
            q.mousePressEvent = functools.partial(self.choose_source_hue,
                                                  source_object=q,
                                                  index=idx)
            self.top_hue_layout.addWidget(q)

        for idx, w in enumerate(range(0, 360, bin_size)):
            if int((idx + 0.5) * bin_size) >= 360:
                break
            q = QLabel()
            q.setAutoFillBackground(True)
            q.setText("  ")

            q.setMargin(5)
            p = q.palette()
            # p.setColor(q.backgroundRole(),QColor.fromHsl(int((idx+0.5)*bin_size), 255, 128, alpha=0))
            q.setPalette(p)
            qc = QColor.fromHsl(int((idx + 0.5) * bin_size), 255, 128, alpha=0)
            q.setStyleSheet("background-color: %s" % (qc.name(QColor.HexArgb)))
            self.mid_hue_layout.addWidget(q)

        for idx, w in enumerate(range(0, 360, bin_size)):
            if int((idx + 0.5) * bin_size) >= 360:
                break
            q = QLabel()
            q.setAutoFillBackground(True)

            q.setMargin(5)
            p = q.palette()
            p.setColor(q.backgroundRole(),
                       QColor.fromHsl(int((idx + 0.5) * bin_size), 255, 128))
            q.setPalette(p)
            q.setStyleSheet("background-color: %s" %
                            (QColor.fromHsl(int(
                                (idx + 0.5) * bin_size), 255, 128).name()))
            q.mousePressEvent = functools.partial(self.choose_target_hue,
                                                  source_object=q,
                                                  index=idx)
            self.bottom_hue_layout.addWidget(q)

    def choose_source_hue(self, event, source_object=None, index=None):
        self.source_hue_idx = index
        pass

    def choose_target_hue(self, event, source_object=None, index=None):
        self.target_hue_idx = index
        if self.source_hue_idx is not None:
            q = self.mid_hue_layout.itemAt(self.source_hue_idx).widget()
            p = q.palette()
            p.setColor(
                q.backgroundRole(),
                QColor.fromHsl(int((self.target_hue_idx + 0.5) * self.binsz),
                               255,
                               128,
                               alpha=255))
            q.setPalette(p)
            qc = QColor.fromHsl(int((self.target_hue_idx + 0.5) * self.binsz),
                                255,
                                128,
                                alpha=255)
            q.setStyleSheet("background-color: %s" % (qc.name(QColor.HexArgb)))
            self.src_tar_mp[self.source_hue_idx] = self.target_hue_idx

            #更新目标颜色 并刷新结果
            self.parent_win.update_target_colors(self.src_tar_mp, self.binsz)
        pass
示例#22
0
class ProblemPage(QWidget):
    def __init__(self, mode, timer):
        super().__init__()
        self.solution_stack = []
        self.start_time = 0
        self.timer = timer
        self.mode = mode
        self.numbers = []
        self.target = 0
        self.back_button = QPushButton("Back")
        self.big_number_count = QSpinBox()
        self.big_number_count.setRange(1, 4)
        self.generate_number_box = QPushButton("Generate")
        self.reset_button = QPushButton("Reset")
        self.reset_button.setDisabled(True)
        self.number_group = QHBoxLayout()
        self.set_numbers = QPushButton("Set Numbers")
        self.set_numbers.setDisabled(True)
        self.number_line()
        self.target_window = QLineEdit("Target")
        self.set_target = QPushButton("Set Target")
        self.set_target.setDisabled(True)
        self.target_check = QLabel("Target should be between 100 and 999")
        self.timer_bar = QProgressBar()
        self.timer_bar.setRange(0, 100)
        self.time_keeper = QTimer()
        self.counter = 0
        self.time_keeper.timeout.connect(lambda: self.timer_props())

        self.setLayout(self.set_layout())

        if self.mode == 0:
            self.generate_number_box.clicked.connect(
                lambda: self.generate_button_mode0_action())
            self.set_numbers.clicked.connect(lambda: self.set_numbers_action())
            self.reset_button.clicked.connect(lambda: self.reset_actions())
            self.set_target.clicked.connect(
                lambda: self.target_button_action())
            self.back_button.clicked.connect(lambda: self.reset_actions())

    def solve(self):
        solver = CountDownSolver(self.big_number_count.value(), self.numbers,
                                 self.target)
        print('Solver started')
        start_time = time.time()
        solver.solve()
        self.solution_stack = solver.solution_stack
        print('solver done')
        end_time = time.time()
        print('solver took :', round(end_time - start_time, 3), 'secs')

    def timer_props(self):
        self.counter += 1
        value = (self.counter / 100) / self.timer * 100
        self.timer_bar.setValue(value)
        if value > 100:
            self.time_keeper.stop()
            self.solve()
            print(self.solution_stack)

    def target_button_action(self):
        try:
            if 100 <= int(self.target_window.text()) <= 999:
                self.set_target.setDisabled(True)
                self.target = int(self.target_window.text())
                print('valid target: ', self.target)

                self.time_keeper.start(1)

            else:
                self.target = 0
                print('target not in range')
        except ValueError:
            print('invalid target')

    def reset_actions(self):
        self.generate_number_box.setDisabled(False)
        self.set_numbers.setDisabled(True)
        self.set_target.setDisabled(True)
        for i in range(self.number_group.count()):
            item = self.number_group.itemAt(i).widget()
            if isinstance(item, QComboBox):
                for j in range(item.count()):
                    item.removeItem(0)

    def set_numbers_action(self):
        self.numbers = []
        for i in range(self.number_group.count()):
            item = self.number_group.itemAt(i).widget()
            if isinstance(item, QComboBox):
                self.numbers.append(int(item.currentText()))
        print(self.numbers)
        self.set_target.setDisabled(False)

    def generate_button_mode0_action(self):
        big = self.big_number_count.value()
        box = 0
        for i in range(self.number_group.count()):
            item = self.number_group.itemAt(i).widget()
            if isinstance(item, QComboBox):
                if box < big:
                    item.addItems(str(25 * j) for j in [1, 2, 3, 4])
                elif big <= box < 6:
                    item.addItems(str(j) for j in range(1, 11))
                box += 1
        self.generate_number_box.setDisabled(True)
        self.set_numbers.setDisabled(False)
        self.reset_button.setDisabled(False)

    def set_layout(self):
        back_line = QHBoxLayout()
        back_line.addStretch(1)
        back_line.addWidget(self.back_button)
        back_line.addStretch(1)

        big_number_line = QHBoxLayout()
        big_number_line.addWidget(QLabel("Big Number Count : "))
        big_number_line.addStretch(1)
        big_number_line.addWidget(self.big_number_count)
        big_number_line.addStretch(1)
        big_number_line.addWidget(self.generate_number_box)
        big_number_line.addStretch(1)
        big_number_line.addWidget(self.reset_button)

        target_line = QHBoxLayout()
        target_line.addWidget(self.target_window)
        target_line.addStretch(1)
        target_line.addWidget(self.set_target)
        target_line.addStretch(1)
        target_line.addWidget(self.target_check)

        main_layout = QVBoxLayout()
        main_layout.addLayout(back_line)
        main_layout.addStretch(1)
        main_layout.addLayout(big_number_line)
        main_layout.addStretch(1)
        main_layout.addLayout(self.number_group)
        main_layout.addStretch(1)
        main_layout.addLayout(target_line)
        main_layout.addStretch(1)
        main_layout.addWidget(self.timer_bar)
        main_layout.addStretch(1)
        return main_layout

    def number_line(self):
        for i in range(6):
            if self.mode == 1:
                self.number_group.addWidget(QLabel(" "))
                self.number_group.addStretch(1)
            elif self.mode == 0:
                self.number_group.addWidget(QComboBox())
                self.number_group.addStretch(1)
        self.number_group.addWidget(self.set_numbers)
示例#23
0
class App(QDialog):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        self.title = 'Stock/ETF Historical Investment Strategy Calculator'

        # create group boxes
        self.createTickerBoxes()
        self.createInstructionBox()
        self.createStratBoxes()
        self.createInitialBox()
        self.createStaticNumbersBoxes()
        self.createIncomeBox()
        self.createAIGRBox()
        self.createInvesFracBox()
        self.createCalculateBox()
        self.createResultsBox()
        self.createExtraBasicBox()
        self.createExtraDateBox()
        self.createErrorBox()
        self.createFinalIncomeBox()

        # create and organize the layout
        mainLayout = QGridLayout()
        mainLayout.addLayout(self.tickerBoxes, 0, 0)
        mainLayout.addLayout(self.instructBoxes, 1, 0)
        mainLayout.addLayout(self.stratBoxes, 2, 0)
        mainLayout.addLayout(self.initialBox, 3, 0)
        mainLayout.addLayout(self.staticNumbersBoxes, 4, 0)
        mainLayout.addLayout(self.incomeBox, 5, 0)
        mainLayout.addLayout(self.aigrBox, 6, 0)
        mainLayout.addLayout(self.investFracBox, 7, 0)
        mainLayout.addLayout(self.calculateBox, 8, 0)
        mainLayout.addLayout(self.errorBox, 9, 0)
        mainLayout.addLayout(self.resultsBox, 0, 1, 7, 10)
        mainLayout.addLayout(self.extraBasicBox, 7, 1)
        mainLayout.addLayout(self.extraDateBox, 8, 1)
        mainLayout.addLayout(self.finalIncomeBox, 9, 1)

        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(1, 10)

        self.createTabs(mainLayout)

        centralLayout = QGridLayout()
        centralLayout.addWidget(self.tabWidget, 0, 0)

        self.setLayout(centralLayout)

        # initializing the app
        self.initUI()

    # initializes the UI
    def initUI(self):
        self.setWindowTitle(self.title)

        self.show()

    # creates the tabs
    def createTabs(self, layout):

        self.tabWidget = QTabWidget()

        tab1 = QWidget()
        tab1.setLayout(layout)

        tab2 = QWidget()
        guideLabel = QLabel("Check boxes for data to be updated:")
        stockLineEdit = QLineEdit("")
        stockCheck = QCheckBox("Ticker: ")

        notesCheck = QCheckBox("Treasury Notes")

        tickerCheck = QCheckBox("Ticker List")

        refreshButton = QPushButton("Update Data")
        refreshButton.clicked.connect(self.clickRefresh)

        errorMessage = QLabel("")

        tab2Box = QVBoxLayout()
        tab2miniBox = QHBoxLayout()

        tab2miniBox.addWidget(stockCheck)
        tab2miniBox.addWidget(stockLineEdit)

        tab2Box.addWidget(guideLabel)
        tab2Box.addLayout(tab2miniBox)
        tab2Box.addWidget(notesCheck)
        tab2Box.addWidget(tickerCheck)
        tab2Box.addWidget(refreshButton)
        tab2Box.addWidget(errorMessage)

        tab2.setLayout(tab2Box)

        tab3 = QWidget()
        inveStratTextEdit = QTextEdit()
        inveStratTextEdit.setPlainText(
            "Investment strategies\n"
            "by ComradeAkko\n\n"
            "The following are the investment strategies that can be used with the\n"
            "function. Static strategies are ones where the only capital used is\n"
            "the initial capital. Active strategies include monthly payments.\n\n\n"
            "Static Strategies\n\n"
            "Buy and Hold (BH):\n"
            "After an initial investment, the shares are held for the entirety of\n"
            "its period. Dividends are not reinvested.\n\n"
            "Regular Momentum Trading (MT):\n"
            "After an intial investment, the shares are held as long as the price\n"
            "is above its 200-day moving average. If the price is below its 200-day\n"
            "moving average, it is sold and transferred to bonds. Dividends are reinvested\n"
            "when a trade is made.\n\n"
            "Golden-Cross Momentum Trading (GX):\n"
            "After an initial investment, shares are held when the price is above\n"
            "both its 200-day and 50-day moving average. If the 50-day moving average\n"
            "crosses below the 200-day moving average, the shares are sold and\n"
            "transferred to bonds. Dividends are reinvested\n"
            "when a trade is made.\n\n\n"
            "Active Strategies\n\n"
            "Dollar-cost Averaging (DCA):\n"
            "After the initial lump-sum investment, every month on the 10th,\n"
            "as many shares as many are allowed are bought regardless of whether\n"
            "prices are high or low. Shares are never sold.\n\n"
            "Parallel Momentum Trading (PMT):\n"
            "After the intial lump-sum investment,every month on the 10th,\n"
            "shares are bought as long as the current price is higher than the 200-day\n"
            "moving average. If the current price drops below the 200-day moving\n"
            "average, the shares are sold and transferred to bonds. Subsequent\n"
            "investment income will be directed to bonds (**parallel** with current\n"
            "investments) until the price of the shares rises above the 200-day\n"
            "moving average again.\n\n"
            "Divergent Momentum Trading (DMT):\n"
            "After the initial lump-sum investment, every month on the 10th,\n"
            "shares are bought as long as the current price is higher than the 200-day\n"
            "moving average. If the current price drops below the 200-day moving\n"
            "average, the shares are sold and transferred to bonds. Subsequent\n"
            "investment income will be directed to stocks (**divergent** with\n"
            "current investmenets) until the price of the shares rises above the\n"
            "200-day moving average again.\n\n"
            "Golden-Cross Parallel Momentum Trading (GPM):\n"
            "A combination of PMT and using both 200-day and 50-day moving averages.\n\n"
            "Golden-Cross Divergent Momentum Trading (GDM):\n"
            "A combination of DMT and using both 200-day and 50-day moving averages."
        )

        tab3hbox = QHBoxLayout()
        tab3hbox.setContentsMargins(5, 5, 5, 5)
        tab3hbox.addWidget(inveStratTextEdit)
        tab3.setLayout(tab3hbox)

        self.tabWidget.addTab(tab1, "&Main")
        self.tabWidget.addTab(tab2, "&Updating Data")
        self.tabWidget.addTab(tab3, "&Investment Strategies")

    # creates a ticker box
    def createTickerBoxes(self):
        self.tickerBoxes = QHBoxLayout()

        # create ticker line edit
        tickerLineEdit = QLineEdit('')

        tickerLabel = QLabel("&Ticker:")
        tickerLabel.setBuddy(tickerLineEdit)

        # create startdate line edit
        startDLineEdit = QLineEdit('')

        startDLabel = QLabel("&Starting Date (MM/DD/YYYY):")
        startDLabel.setBuddy(startDLineEdit)

        # create enddate line edit
        endDLineEdit = QLineEdit('')

        endDLabel = QLabel("&Ending Date (MM/DD/YYYY):")
        endDLabel.setBuddy(endDLineEdit)

        # adding all widgets to the boxlayout
        self.tickerBoxes.addWidget(tickerLabel)
        self.tickerBoxes.addWidget(tickerLineEdit)
        self.tickerBoxes.addStretch(1)
        self.tickerBoxes.addWidget(startDLabel)
        self.tickerBoxes.addWidget(startDLineEdit)
        self.tickerBoxes.addWidget(endDLabel)
        self.tickerBoxes.addWidget(endDLineEdit)

    # creates an instruction box
    def createInstructionBox(self):
        self.instructBoxes = QHBoxLayout()

        instructLabel = QLabel(
            "^Note: Dates also accept the answer 'MAX' to indicate the earliest/latest date in both start/end dates.\n"
        )

        self.instructBoxes.addWidget(instructLabel)

    # creates a strategy box
    def createStratBoxes(self):
        self.stratBoxes = QHBoxLayout()

        # create list of strategies
        stratList = ["BH", "MT", "GX", "DCA", "DMT", "PMT", "GDM", "GPM"]

        # create a strat1 combo box
        strat1ComboBox = QComboBox()
        strat1ComboBox.addItems(stratList)

        strat1Label = QLabel("&Strategy 1:")
        strat1Label.setBuddy(strat1ComboBox)

        # create a strat2 combo box
        strat2ComboBox = QComboBox()
        strat2ComboBox.addItems(stratList)

        strat2Label = QLabel("&Strategy 2:")
        strat2Label.setBuddy(strat2ComboBox)

        # create a strat3 combo box
        strat3ComboBox = QComboBox()
        strat3ComboBox.addItems(stratList)

        strat3Label = QLabel("&Strategy 3:")
        strat3Label.setBuddy(strat3ComboBox)

        # adding all widgets to the boxlayout
        self.stratBoxes.addWidget(strat1Label)
        self.stratBoxes.addWidget(strat1ComboBox)
        self.stratBoxes.addStretch(1)
        self.stratBoxes.addWidget(strat2Label)
        self.stratBoxes.addWidget(strat2ComboBox)
        self.stratBoxes.addStretch(1)
        self.stratBoxes.addWidget(strat3Label)
        self.stratBoxes.addWidget(strat3ComboBox)

    # creates a box that contains the initial capital
    def createInitialBox(self):
        self.initialBox = QHBoxLayout()

        # create a intial capital line edit
        initialLineEdit = QLineEdit('10000')

        initialLabel = QLabel("&Initial capital:")
        initialLabel.setBuddy(initialLineEdit)

        # add the widget
        self.initialBox.addWidget(initialLabel)
        self.initialBox.addWidget(initialLineEdit)

    # creates a box that contains the baseSMA and the commission values
    def createStaticNumbersBoxes(self):
        self.staticNumbersBoxes = QHBoxLayout()

        # create baseSMA line edit
        baseSMALineEdit = QLineEdit('200')

        baseSMALabel = QLabel("&Base moving average period (days):")
        baseSMALabel.setBuddy(baseSMALineEdit)

        # create commission line edit
        commissionLineEdit = QLineEdit('5')

        commissionLabel = QLabel("Commission:")
        commissionLabel.setBuddy(commissionLineEdit)

        # adding all widgets to the boxlayout
        self.staticNumbersBoxes.addWidget(baseSMALabel)
        self.staticNumbersBoxes.addWidget(baseSMALineEdit)
        self.staticNumbersBoxes.addStretch(1)
        self.staticNumbersBoxes.addWidget(commissionLabel)
        self.staticNumbersBoxes.addWidget(commissionLineEdit)

    # creates a box that contains the income
    def createIncomeBox(self):
        self.incomeBox = QHBoxLayout()

        # create income line edit
        incomeLineEdit = QLineEdit('0')

        incomeLabel = QLabel("&Annual pre-taxed income:")
        incomeLabel.setBuddy(incomeLineEdit)

        # adding all widgets to the boxlayout
        self.incomeBox.addWidget(incomeLabel)
        self.incomeBox.addWidget(incomeLineEdit)

    # creates a box containing the aigr
    def createAIGRBox(self):
        self.aigrBox = QHBoxLayout()

        # create annual income growth rate line edit
        aigrLineEdit = QLineEdit('0')

        aigrLabel = QLabel(
            "&Annual income growth rate in decimal (i.e. 0.02):")
        aigrLabel.setBuddy(aigrLineEdit)

        # add the widget
        self.aigrBox.addWidget(aigrLabel)
        self.aigrBox.addWidget(aigrLineEdit)

    # creates a box containing the investment fraction box
    def createInvesFracBox(self):
        self.investFracBox = QHBoxLayout()

        # create the investment fraction line edit
        invesFracLineEdit = QLineEdit('0')

        invesFracLabel = QLabel(
            "&Fraction of income reserved to investment in decimal (i.e. 0.5):"
        )
        invesFracLabel.setBuddy(invesFracLineEdit)

        # add the widget
        self.investFracBox.addWidget(invesFracLabel)
        self.investFracBox.addWidget(invesFracLineEdit)

    # create a box that contains the calculate button
    def createCalculateBox(self):
        self.calculateBox = QHBoxLayout()

        # create calculate line edit
        calculateButton = QPushButton('Calculate', self)
        calculateButton.setToolTip('This is an example button')
        calculateButton.clicked.connect(self.clickCalculate)

        self.calculateBox.addWidget(calculateButton)

    # create a box that contains the results
    def createResultsBox(self):
        self.resultsBox = QHBoxLayout()

        # create a table for results
        resultsTable = QTableWidget(7, 3)
        resultsTable.horizontalHeader().setStretchLastSection(True)

        # Inputting info
        header0 = QTableWidgetItem("Commission:")
        headerz = QTableWidgetItem("Commission:")
        header1 = QTableWidgetItem("Taxes:")
        header2 = QTableWidgetItem("Treasury Yield:")
        header3 = QTableWidgetItem("Dividend received:")
        header4 = QTableWidgetItem("Profit/loss from trading:")
        header5 = QTableWidgetItem("Final Assets:")
        header6 = QTableWidgetItem("CAGR:")
        header7 = QTableWidgetItem("strategy1")
        header8 = QTableWidgetItem("strategy2")
        header9 = QTableWidgetItem("strategy3")
        resultsTable.setVerticalHeaderItem(0, header0)
        resultsTable.setVerticalHeaderItem(1, header1)
        resultsTable.setVerticalHeaderItem(2, header2)
        resultsTable.setVerticalHeaderItem(3, header3)
        resultsTable.setVerticalHeaderItem(4, header4)
        resultsTable.setVerticalHeaderItem(5, header5)
        resultsTable.setVerticalHeaderItem(6, header6)
        resultsTable.setHorizontalHeaderItem(0, header7)
        resultsTable.setHorizontalHeaderItem(1, header8)
        resultsTable.setHorizontalHeaderItem(2, header9)

        self.resultsBox.addWidget(resultsTable)

    # create more results boxes that contain the ticker and initial capital info
    def createExtraBasicBox(self):
        self.extraBasicBox = QHBoxLayout()

        # create labels to contain the basic info
        basicTickerLabel = QLabel("Ticker: ")
        basicInitialLabel = QLabel("Initial Capital: ")
        self.extraBasicBox.addWidget(basicTickerLabel)
        self.extraBasicBox.addWidget(basicInitialLabel)

    # create more results boxes that contain the start/end date info
    def createExtraDateBox(self):
        self.extraDateBox = QHBoxLayout()

        # create labels to contain the basic info
        basicStartDate = QLabel("Start Date: ")
        basicEndDate = QLabel("End date: ")
        self.extraDateBox.addWidget(basicStartDate)
        self.extraDateBox.addWidget(basicEndDate)

    # create error boxes that display errors
    def createErrorBox(self):
        self.errorBox = QHBoxLayout()
        errorLabel = QLabel(" ")
        self.errorBox.addWidget(errorLabel)

    # creates an error box that displays final incomes
    def createFinalIncomeBox(self):
        self.finalIncomeBox = QHBoxLayout()
        finalIncomeLabel = QLabel("Final Income: ")
        self.finalIncomeBox.addWidget(finalIncomeLabel)

    # what to do when calculate button is pushed
    @pyqtSlot()
    def clickCalculate(self):
        # get all the inputs
        ticker = self.tickerBoxes.itemAt(1).widget().text()
        startDate = self.tickerBoxes.itemAt(4).widget().text()
        endDate = self.tickerBoxes.itemAt(6).widget().text()
        strat1 = self.stratBoxes.itemAt(1).widget().currentText()
        strat2 = self.stratBoxes.itemAt(4).widget().currentText()
        strat3 = self.stratBoxes.itemAt(7).widget().currentText()

        # make sure the values are all numbers
        numbers = True
        try:
            capital = float(self.initialBox.itemAt(1).widget().text())
            sma = int(self.staticNumbersBoxes.itemAt(1).widget().text())
            commission = float(
                self.staticNumbersBoxes.itemAt(4).widget().text())
            income = float(self.incomeBox.itemAt(1).widget().text())
            aigr = float(self.aigrBox.itemAt(1).widget().text())
            invesFrac = float(self.investFracBox.itemAt(1).widget().text())
        except ValueError:
            numbers = False

        if numbers:
            # get the results
            results = investCalc(ticker, startDate, endDate, capital, income,
                                 strat1, strat2, strat3, sma, commission,
                                 invesFrac, aigr)

            if results.errorBoo == False:
                # sort out the data
                data1 = results.strat1
                data2 = results.strat2
                data3 = results.strat3

                # print the results
                table = self.resultsBox.itemAt(0).widget()

                # for strategy 1
                strat1 = QTableWidgetItem(data1.type)
                assets1 = QTableWidgetItem(str(round(data1.assets, 2)))
                cagr1 = QTableWidgetItem(str(round(data1.cagr, 4)))
                taxes1 = QTableWidgetItem(str(round(data1.taxes, 2)))
                commission1 = QTableWidgetItem(str(round(data1.comissions, 2)))
                pl1 = QTableWidgetItem(str(round(data1.pl, 2)))
                div1 = QTableWidgetItem(str(round(data1.div, 2)))
                treasury1 = QTableWidgetItem(str(round(data1.treasury, 2)))

                table.setHorizontalHeaderItem(0, strat1)
                table.setItem(0, 0, commission1)
                table.setItem(1, 0, taxes1)
                table.setItem(2, 0, treasury1)
                table.setItem(3, 0, div1)
                table.setItem(4, 0, pl1)
                table.setItem(5, 0, assets1)
                table.setItem(6, 0, cagr1)

                # for strategy 2
                strat2 = QTableWidgetItem(data2.type)
                assets2 = QTableWidgetItem(str(round(data2.assets, 2)))
                cagr2 = QTableWidgetItem(str(round(data2.cagr, 4)))
                taxes2 = QTableWidgetItem(str(round(data2.taxes, 2)))
                commission2 = QTableWidgetItem(str(round(data2.comissions, 2)))
                pl2 = QTableWidgetItem(str(round(data2.pl, 2)))
                div2 = QTableWidgetItem(str(round(data2.div, 2)))
                treasury2 = QTableWidgetItem(str(round(data2.treasury, 2)))

                table.setHorizontalHeaderItem(1, strat2)
                table.setItem(0, 1, commission2)
                table.setItem(1, 1, taxes2)
                table.setItem(2, 1, treasury2)
                table.setItem(3, 1, div2)
                table.setItem(4, 1, pl2)
                table.setItem(5, 1, assets2)
                table.setItem(6, 1, cagr2)

                # for strategy 3
                strat3 = QTableWidgetItem(data3.type)
                assets3 = QTableWidgetItem(str(round(data3.assets, 2)))
                cagr3 = QTableWidgetItem(str(round(data3.cagr, 4)))
                taxes3 = QTableWidgetItem(str(round(data3.taxes, 2)))
                commission3 = QTableWidgetItem(str(round(data3.comissions, 2)))
                pl3 = QTableWidgetItem(str(round(data3.pl, 2)))
                div3 = QTableWidgetItem(str(round(data3.div, 2)))
                treasury3 = QTableWidgetItem(str(round(data3.treasury, 2)))

                table.setHorizontalHeaderItem(2, strat3)
                table.setItem(0, 2, commission3)
                table.setItem(1, 2, taxes3)
                table.setItem(2, 2, treasury3)
                table.setItem(3, 2, div3)
                table.setItem(4, 2, pl3)
                table.setItem(5, 2, assets3)
                table.setItem(6, 2, cagr3)

                # set the other basic info
                tickerBasics = "Ticker: " + results.ticker
                initialBasics = "Initial Capital: " + str(round(capital, 2))

                startBasics = "Start Date: " + data1.iDate
                endBasics = "End Date: " + data1.pDate

                incomeBasics = "Final Income: " + str(round(results.income, 2))

                self.extraBasicBox.itemAt(0).widget().setText(tickerBasics)
                self.extraBasicBox.itemAt(1).widget().setText(initialBasics)
                self.extraDateBox.itemAt(0).widget().setText(startBasics)
                self.extraDateBox.itemAt(1).widget().setText(endBasics)
                self.finalIncomeBox.itemAt(0).widget().setText(incomeBasics)

                error = " "
                self.errorBox.itemAt(0).widget().setText(error)

            else:
                error = "Error: " + results.errorMess
                self.errorBox.itemAt(0).widget().setText(error)

        else:
            error = "Error: One or more of the number inputs do not contain valid numbers, please try again."
            self.errorBox.itemAt(0).widget().setText(error)

    # what to do when the refresh button is pushed
    def clickRefresh(self):
        ticker = self.tabWidget.widget(1).layout().itemAt(1).layout().itemAt(
            1).widget().text()
        stockBool = self.tabWidget.widget(1).layout().itemAt(
            1).layout().itemAt(0).widget().isChecked()
        notesBool = self.tabWidget.widget(1).layout().itemAt(
            2).widget().isChecked()
        tickerBool = self.tabWidget.widget(1).layout().itemAt(
            3).widget().isChecked()

        # if the stock check box is checked
        if stockBool:
            # if the ticker exists
            if tickerExists(ticker):
                getStockData(ticker)
                if notesBool:
                    getTreasuryData()
                if tickerBool:
                    getTickerList()
                self.tabWidget.widget(1).layout().itemAt(5).widget().setText(
                    "Update done.")
            else:
                self.tabWidget.widget(1).layout().itemAt(5).widget().setText(
                    "Error: ticker does not exist")
        else:
            if notesBool:
                getTreasuryData()
            if tickerBool:
                getTickerList()
            self.tabWidget.widget(1).layout().itemAt(5).widget().setText(
                "Update done.")
示例#24
0
class Game(QWidget):
    add_number_signal = pyqtSignal(tuple)
    pop_number_signal = pyqtSignal()
    rotate_signal = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.move(20, 20)
        self.hbox = QHBoxLayout()
        self.grid = Grid(self)
        self.vbox = QVBoxLayout()
        self.actual_piece = Piece("blank", self)
        self.rotate_button = QPushButton('Rotar', self)
        self.end_game_button = QPushButton('Terminar Juego', self)
        self.back_button = QPushButton('Retroceder', self)
        self.save_button = QPushButton('Guardar', self)
        self.state_grid = StateGrid(self)
        self.p1_points = QLabel(self)
        self.p2_points = QLabel(self)
        self.set_points(1, 0)
        self.set_points(2, 0)

    def initUi(self):
        self.setWindowTitle('Best Tarea Ever :P')
        self.setMouseTracking(True)
        self.setLayout(self.hbox)
        self.hbox.addStretch(1)
        self.hbox.addWidget(self.grid)
        self.hbox.addStretch(1)
        self.hbox.addLayout(self.vbox)
        self.hbox.addStretch(1)
        self.grid.show()
        self.piece_layout = QHBoxLayout(self)
        self.piece_layout.addStretch(1)
        self.piece_layout.addWidget(self.actual_piece)
        self.piece_layout.addStretch(1)
        self.vbox.addStretch(1)
        self.vbox.addLayout(self.piece_layout)
        self.vbox.addStretch(1)
        hlayout = QHBoxLayout(self)
        self.vbox.addLayout(hlayout, 1)
        hlayout.addWidget(self.save_button, 1)
        hlayout.addWidget(self.rotate_button, 1)
        hlayout.addWidget(self.end_game_button, 1)
        hlayout.addWidget(self.back_button, 1)
        self.vbox.addStretch(1)
        self.vbox.addWidget(self.state_grid, 1)
        hlayout_points = QHBoxLayout(self)
        self.vbox.addLayout(hlayout_points, 1)
        self.p1_points.show()
        self.p2_points.show()
        hlayout_points.addWidget(self.p1_points)
        hlayout_points.addWidget(self.p2_points)
        self.rotate_button.clicked.connect(self.rotate_piece)
        self.back_button.clicked.connect(self.back_move)
        self.end_game_button.clicked.connect(self.end_game)
        self.save_button.clicked.connect(self.save_game)
        self.add_number_signal.connect(self.state_grid.add_number)
        self.pop_number_signal.connect(self.state_grid.pop_number)
        self.rotate_signal.connect(self.rotate_piece)
        self.grid.initUI()
        self.new_piece()

    @staticmethod
    def back_move():
        variables.GAME_INTERFACE.retroceder()

    @staticmethod
    def end_game():
        variables.GAME_INTERFACE.terminar_juego()

    @staticmethod
    def save_game():
        variables.GAME_INTERFACE.guardar_juego()

    def user_rotate(self):
        self.rotate_signal.emit()

    def add_number(self, number, color):
        self.add_number_signal.emit((number, color))

    def pop_number(self):
        self.pop_number_signal.emit()

    def new_piece(self, color=None, piece_type=None):
        if piece_type is None:
            piece_type = choice(variables.TYPES)
        if color is None and piece_type != "hint":
            color = choice(variables.COLORS)
        self.piece_layout.removeItem(self.piece_layout.itemAt(2))
        self.piece_layout.removeWidget(self.actual_piece)
        self.actual_piece.hide()
        self.actual_piece.deleteLater()
        self.actual_piece = Piece(piece_type, color, self)
        self.piece_layout.addWidget(self.actual_piece)
        self.piece_layout.addStretch(1)

    def addPiece(self, i, j, color=None, piece_type=None, on_move_ended=None):
        if piece_type is None:
            self.grid.addPiece(i, j, self.actual_piece, on_move_ended)
        elif piece_type == 'blank' or piece_type == 'hint':
            self.grid.addPiece(i, j, Piece(piece_type, color, self.grid))
        else:
            raise TypeError('No es un tipo valido')

    def getPiece(self, i, j):
        return self.grid.getPiece(i, j)

    def popPiece(self, i, j):
        pop_piece = self.grid.popPiece(i, j)
        self.addPiece(i, j, piece_type='blank')
        return pop_piece

    def movePiece(self, i, j, piece, on_move_end=None):
        self.grid.movePiece(i, j, piece, on_move_end)

    def set_points(self, player_numb, points):
        # self.label_puntaje.setText(str(points))
        if player_numb == 1:
            self.p1_points.setText("Jugador 1: {}".format(points))
        elif player_numb == 2:
            self.p2_points.setText("Jugador 2: {}".format(points))

    def rotate_piece(self):
        self.actual_piece.rotate()
        variables.GAME_INTERFACE.rotar_pieza('Derecha')

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_H:
            variables.GAME_INTERFACE.hint_asked()
示例#25
0
class MainWindow(QMainWindow):
    def __init__(self, dataBaseName):
        super().__init__()
        self._dataBase = myDatabase.MyDataBase(dataBaseName)

        self._dictexe = {
            "первый запрос": (self.firstQuery, self.firstExe),
            "второй запрос": (self.secondQuery, self.secondExe),
            "третий запрос": (self.thirdQuery, self.thirdExe)
        }

        self._view = QTreeView()

        self._buttonAdd = QPushButton("Добавить")
        self._buttonAdd.clicked.connect(self.getItems)
        self._addSpinBox = QSpinBox()
        self._addComboBox = QComboBox()
        self._addComboBox.addItems(self._dataBase.dishes())

        self._layout = QHBoxLayout()
        self._qSpinBox = QSpinBox()
        self._qComboBox = QComboBox()
        self._qLineEdit = QLineEdit()
        self._qCalendarWidget = QCalendarWidget()

        self._queryDisc = QLabel()

        self._buttonExe = QPushButton("Исполнить")
        self._buttonExe.clicked.connect(self.onButtonExe)

        self._combox = QComboBox()
        self._combox.currentTextChanged.connect(self.comboChanged)
        self._combox.addItems(self._dictexe.keys())

        self.initUi()

    def initUi(self):
        self.setGeometry(300, 300, 200, 200)
        self.setWindowTitle('Ресторан')
        #self.setWindowIcon(QIcon(''))

        w = QWidget()

        mainLayout = QVBoxLayout()
        w.setLayout(mainLayout)

        self.setCentralWidget(w)

        mainLayout.addWidget(self._view)

        tmpLayout = QHBoxLayout()
        mainLayout.addLayout(tmpLayout)
        tmpLayout.addWidget(QLabel("Добавления ингредиента"))
        tmpLayout.addWidget(self._addSpinBox)
        tmpLayout.addWidget(self._addComboBox)
        tmpLayout.addWidget(self._buttonAdd)

        mainLayout.addWidget(self._queryDisc)

        tmpLayout = QHBoxLayout()
        mainLayout.addLayout(tmpLayout)
        tmpLayout.addWidget(self._combox)
        tmpLayout.addLayout(self._layout)
        tmpLayout.addWidget(self._buttonExe)

        self.adjustSize()

    def comboChanged(self, text):
        self._dictexe[text][0]()

    def clearLayout(self):
        while self._layout.count() > 0:
            self._layout.itemAt(0).widget().setParent(None)

    #Названия и калорийность блюд по рецептам автора X
    def firstQuery(self):
        self._queryDisc.setText(
            "Названия и калорийность блюд по рецептам автора X")
        self.clearLayout()
        #self._qSpinBox.setValue(0)
        #self._layout.insertWidget(1,self._qSpinBox)
        self._qComboBox.clear()
        self._qComboBox.addItems(self._dataBase.authors())
        self._layout.insertWidget(1, self._qComboBox)

    def firstExe(self):
        model = self._dataBase.first(self._qComboBox.currentText())
        self.setModel(model)

    #Названия ресторанов, к которым относятся повара, готовящие блюда содержащие в
    #названии подстроку X (например, «картофельный»), отсортированные по алфавиту
    def secondQuery(self):
        self._queryDisc.setText(
            "Названия ресторанов, к которым относятся повара,\n готовящие блюда содержащие в названии подстроку X (например, «картофельный»),\n отсортированные по алфавиту"
        )
        self.clearLayout()
        self._qLineEdit.clear()
        self._layout.insertWidget(1, self._qLineEdit)

    def secondExe(self):
        model = self._dataBase.second(self._qLineEdit.text())
        self.setModel(model)

    #Названия и количества ингредиентов и названия мероприятий, на которых разливают
    #напитки в количестве меньше X после даты Y
    def thirdQuery(self):
        self._queryDisc.setText(
            "Названия и количества ингредиентов и названия мероприятий, на которых разливают\n напитки в количестве меньше X после даты Y"
        )
        self.clearLayout()
        self._layout.insertWidget(1, self._qCalendarWidget)
        self._qSpinBox.setMaximum(self._dataBase.maxDrinkCount() * 10)
        self._qSpinBox.setValue(0)
        self._layout.insertWidget(1, self._qSpinBox)

    def thirdExe(self):
        model = self._dataBase.third(
            self._qSpinBox.value(),
            self._qCalendarWidget.selectedDate().toPyDate())
        self.setModel(model)

    def setModel(self, model):
        if model is None:
            return
        self._view.setVisible(False)
        self._view.setModel(model)
        for i in range(model.columnCount()):
            self._view.resizeColumnToContents(i)
        self._view.setVisible(True)
        self.adjustSize()

    def onButtonExe(self):
        self._dictexe[self._combox.currentText()][1]()

    def getItems(self):
        name, ok = QInputDialog.getText(self, "Ингредиент", "Введите название")
        if not ok:
            return

        self._dataBase.add(self._addSpinBox.value(),
                           self._addComboBox.currentText(), name)
示例#26
0
class ProjectsWindow(QMdiSubWindow):
    def __init__(self, app, OAuth_token, parent):
        super().__init__()

        self.app = app
        self.token = OAuth_token
        self.parent = parent

        self.open_windows = self.parent.open_windows

        self.initFig()
        self.initUI()

    def initFig(self):
        """
        Initialize Figshare information
        """
        self.project_list = self.get_project_list(self.token)

    def initUI(self):

        self.format_window()

        # Create a horizontal box layout to hold the project buttons
        self.project_buttons_box = QHBoxLayout()
        # Create a vertical box layout to hold the project window widgets and layouts
        self.vbox = QVBoxLayout()

        # Add the Projects button to the vertical box layout
        init_finish = len(self.project_list)
        if init_finish > 4:
            init_finish = 4
        self.create_project_bar(0, init_finish)
        self.vbox.addLayout(self.project_buttons_box)

        # Add the scroll bar to the vertical box layout
        self.s_bar = self.scroll_bar()
        self.vbox.addWidget(self.s_bar)

        self.hbox = QHBoxLayout()
        temp = QVBoxLayout()
        temp.addWidget(self.search_bar())
        temp.addLayout(self.management_buttons())
        self.hbox.addLayout(temp)
        self.hbox.addLayout(self.vbox)

        # Create a central widget for the projects window
        window_widget = QWidget()
        # Add the vertical box layout
        window_widget.setLayout(self.hbox)
        # Set the projects window widget
        self.setWidget(window_widget)

    #####
    # Window Formatting
    #####

    def format_window(self):
        """
        Formats the Projects window
        """
        # Gets the QRect of the main window
        geom = self.parent.geometry()
        # Gets the Qrect of the sections window
        section_geom = self.parent.section_geom

        # Define geometries for the projects window
        x0 = section_geom.x() + section_geom.width()
        y0 = section_geom.y()
        w = geom.width() - x0
        h = ((geom.height() - y0) / 6)
        self.setGeometry(x0, y0, w, h)
        # Remove frame from projects window
        self.setWindowFlags(Qt.FramelessWindowHint)

    #####
    # Window Widgets
    #####

    def scroll_bar(self):
        """
        Creates a scroll bar set to the size of the projects list
        :return: QScrollBar Object
        """
        s_bar = QScrollBar(Qt.Horizontal)
        s_bar.setMaximum(len(self.project_list) - 4)
        s_bar.sliderMoved.connect(self.slider_val)
        s_bar.valueChanged.connect(self.slider_val)
        return s_bar

    def create_proj_thumb(self, title, published_date, project_id):
        """
        Creates a large pushbutton for a project
        :param title: string. Project title
        :param published_date: string. project published date
        :param id: int. figshare project id number
        :return: QPushButton object
        """
        geom = self.geometry()

        # Get the scalig ratios for the current window
        w_ratio, f_ratio = scaling_ratio(self.app)
        # Scale the font sizes
        title_fnt_size = 12 * f_ratio
        date_ftn_size = 8 * f_ratio

        # Create the title label
        title_lbl = QLabel()
        title_lbl.setText("{}".format(title))
        title_lbl_fnt = QFont('SansSerif', title_fnt_size)
        title_lbl_fnt.setBold(True)
        title_lbl.setFont(title_lbl_fnt)
        title_lbl.setWordWrap(True)

        # Create the date label
        date_lbl = QLabel()
        if published_date is None:
            published_date = 'Private'
        date_lbl.setText("Published: {}".format(published_date))
        date_lbl_fnt = QFont('SansSerif', date_ftn_size)
        date_lbl.setFont(date_lbl_fnt)
        date_lbl.setStyleSheet('color: gray')
        date_lbl.setWordWrap(True)

        # Create a layout to hold the labels
        lbl_box = QVBoxLayout()
        # Add labels to layout
        lbl_box.addWidget(title_lbl)
        lbl_box.addWidget(date_lbl)

        # Create a button for the project
        btn = QPushButton(self)
        checkable_button(self.app, btn)
        btn.setLayout(lbl_box)
        btn.clicked[bool].connect(lambda: self.on_project_pressed(project_id))

        self.project_buttons_box.addWidget(btn)

    def create_project_bar(self, start, finish):
        """
        Creates a series of Project push buttons
        :param start: start position in projects list
        :param finish: finish position in projects list
        """
        self.buttons = {}
        i = 0
        for project_pos in range(start, finish):
            title = self.project_list[project_pos]['title']
            pub_date = self.project_list[project_pos]['published_date']
            project_id = self.project_list[project_pos]['id']
            self.create_proj_thumb(title, pub_date, project_id)
            self.buttons[project_id] = self.project_buttons_box.itemAt(
                i).widget()
            i += 1

    def management_buttons(self):
        """
        Creates a layout that holds buttons to be used for creating and deleting projects
        :return: QVBoxLayout holding the create, and delete projects buttons
        """

        # Create New Project Button
        np_btn = QPushButton()
        np_btn.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
        np_btn.setIcon(
            QIcon(os.path.abspath(__file__ + '/../..' + '/img/Folder-48.png')))
        np_btn.setToolTip('Create a new Figshare Project')
        np_btn.setToolTipDuration(1)
        np_btn.pressed.connect(self.on_projects_btn_pressed)

        # Create Delete Project Button
        del_btn = QPushButton()
        del_btn.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
        del_btn.setIcon(
            QIcon(os.path.abspath(__file__ + '/../..' +
                                  '/img/del_folder.png')))
        del_btn.setToolTip('Delete Selected Project')
        del_btn.setToolTipDuration(1)
        del_btn.pressed.connect(self.on_delete_btn_pressed)

        # Create layout to hold buttons
        hbox = QHBoxLayout()
        # Add Buttons to layout
        hbox.addWidget(np_btn)
        hbox.addWidget(del_btn)

        return hbox

    def search_bar(self):
        """
        Creates a QLineEdit object for the user to enter a search query
        :return: Edits the projects list object according to the filter
        """

        # Create text box
        edit = QLineEdit()
        # Set font style
        search_bar(self.app, edit)
        # Set place holder text
        edit.setPlaceholderText('Search')
        # Add a clear button to the line edit
        edit.setClearButtonEnabled(True)
        # Add mouse over text
        edit.setToolTip('Search for specific Figshare Projects')
        edit.setToolTipDuration(1)
        # Connect search function to the return key
        edit.returnPressed.connect(lambda: self.search_on_return(edit.text()))
        edit.textChanged.connect(lambda: self.search_on_clear(edit.text()))
        return edit

    #####
    # Widget Actions
    #####

    def slider_val(self):
        """
        Called when the projects button slider is changed.
        Removes all existing buttons and regenerates from the new position
        :return:
        """
        while self.project_buttons_box.count():
            item = self.project_buttons_box.takeAt(0)
            item.widget().deleteLater()

        s_bar_pos = self.s_bar.value()

        if 1 < len(self.project_list) < 4:
            number = len(self.project_list)
        else:
            number = 4
        self.s_bar.setMaximum(len(self.project_list) - number)

        self.create_project_bar(s_bar_pos, s_bar_pos + number)

    def search_init(self):
        """
        Called when the projects search bar is used.
        Removes all existing buttons and regenerates from new projects list
        :return:
        """
        while self.project_buttons_box.count():
            item = self.project_buttons_box.takeAt(0)
            item.widget().deleteLater()

        if 1 <= len(self.project_list) <= 4:
            number = len(self.project_list)
        else:
            number = 4

        self.s_bar.setMaximum(len(self.project_list) - number)

        self.create_project_bar(0, number)

    def search_on_return(self, search_text):
        """
        Called when return is pressed in the search bar.
        :return:
        """
        if search_text != '':
            self.project_list = self.search_projects(search_text, self.token)
            self.search_init()

    def search_on_clear(self, lineedit_text):
        """
        Called when the search bar is cleared
        :return:
        """
        if lineedit_text == '':
            self.project_list = self.get_project_list(self.token)
            self.slider_val()

    def on_projects_btn_pressed(self):
        """
        Called when the create new project button is pressed
        """
        if 'new_project_window' in self.open_windows:
            self.open_windows.remove('new_project_window')
            self.parent.new_project_window.close()
        else:
            self.open_windows.remove('projects_window')
            self.close()

            if 'project_info_window' in self.open_windows:
                self.parent.project_info_window.close()
                self.open_windows.remove('project_info_window')
            if 'project_articles_window' in self.open_windows:
                self.parent.project_articles_window.close()
                self.open_windows.remove('project_articles_window')
            if 'article_edit_window' in self.open_windows:
                self.open_windows.remove('article_edit_window')
                self.parent.article_edit_window.close()

            self.open_windows.add('new_project_window')
            self.parent.new_project_window = NewProjectWindow(
                self.app, self.token, self.parent)
            self.parent.mdi.addSubWindow(self.parent.new_project_window)
            self.parent.new_project_window.show()

    def on_project_pressed(self, project_id):
        """
        Called when a project is clicked.
        :return:
        """
        # For if there is already a project info window open
        if 'project_info_window' in self.open_windows:
            # Get the project id number of the current window
            open_proj = self.parent.project_info_window.project_id

            # For a different project than the currently open project
            if open_proj != project_id:
                # If the current project is in the current view of project buttons (it may have been scrolled away from)
                if open_proj in self.buttons:
                    # If that button is checked, uncheck it
                    if self.buttons[open_proj].isChecked():
                        self.buttons[open_proj].toggle()
                # Close the currently open project info window
                self.parent.project_info_window.close()
                # Create a new project info window for the different project
                self.parent.project_info_window = ProjectInfoWindow(
                    self.app, self.token, self.parent, project_id)
                # Add it as a sub window to the framing window
                self.parent.mdi.addSubWindow(self.parent.project_info_window)
                self.parent.project_info_window.show()

            # If the current projects button is pressed
            else:
                # Close the window and remove from the open window list
                self.open_windows.remove('project_info_window')
                self.parent.project_info_window.close()

            # If any sub windows are open close them as well
            if 'project_articles_window' in self.open_windows:
                self.open_windows.remove('project_articles_window')
                self.parent.project_articles_window.close()
            if 'article_edit_window' in self.open_windows:
                self.open_windows.remove('article_edit_window')
                self.parent.article_edit_window.close()

        # For when no project info window is open
        else:
            self.open_windows.add('project_info_window')
            self.parent.project_info_window = ProjectInfoWindow(
                self.app, self.token, self.parent, project_id)
            self.parent.mdi.addSubWindow(self.parent.project_info_window)
            self.parent.project_info_window.show()

    def on_delete_btn_pressed(self):
        """
        Called when the project delete button is pressed/
        :return:
        """
        open_proj = self.parent.project_info_window.project_id
        project_title = self.parent.project_info_window.project_info['title']

        msg = "Are you sure you want to delete Figshare Project: {}".format(
            project_title)
        msg_box = QMessageBox.question(self, 'Message', msg, QMessageBox.Yes,
                                       QMessageBox.No)

        if msg_box == QMessageBox.Yes:
            successful = self.delete_project(self.token, open_proj)

            if successful:
                con_reply = QMessageBox.information(
                    self, 'Deletion Confirmation',
                    'Project successfully deleted', QMessageBox.Ok)
                if con_reply == QMessageBox.Ok:
                    self.reopen_projects()
                else:
                    self.reopen_projects()
            else:
                con_reply = QMessageBox.warning(
                    self, 'Deletion Confirmation',
                    'Unknown error occurred.\n Project may not have been deleted.',
                    QMessageBox.Ok)
                if con_reply == QMessageBox.Ok:
                    self.reopen_projects()
                else:
                    self.reopen_projects()

    def reopen_projects(self):
        """
        Called to open and close the projects window.
        :return:
        """
        for i in range(2):
            self.parent.section_window.on_projects_btn_pressed()

    #####
    # Figshare API Interface Calls
    #####

    def get_project_list(self, token):
        """
        Returns the users private project list
        :param token: Figshare OAuth token
        :return: array of project
        """
        projects = Projects(token)
        return projects.get_list()

    def search_projects(self, search_text, token):
        """
        Returns a list of projects matching the users search criteria
        :param search_text: String. Figshare style elastic search string
        :param token: Figshare OAuth token
        :return:
        """
        projects = Projects(token)

        result = projects.search(search_text)
        if len(result) == 0:
            result = projects.get_list()

        return result

    def delete_project(self, token, project_id):
        """
        Deletes the given project from Figshare
        :param token:
        :param project_id: Int. Figshare project ID number
        :return:
        """
        projects = Projects(token)
        try:
            projects.delete(
                project_id, safe=False
            )  # Suppresses command line requirement for acknowledgement
            return True
        except:
            return False
示例#27
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.record = -1
        self.inspected = None
        self.oob_update = False
        prefs = QSettings()
        prefs.beginGroup("/General")
        timeout = prefs.value("/Timeout")
        dark_mode = prefs.value("/DarkMode")
        prefs.endGroup()

        # Instantiate core objects
        self.timeout_timer = QTimer()
        self.timeout_timer.setTimerType(Qt.VeryCoarseTimer)
        self.timeout_timer.setInterval(timeout * 1000)
        self.timeout_timer.setSingleShot(True)
        self.timeout_timer.timeout.connect(self.update_temp_log)
        self.systems = ActionsWidget(LogSource.SYSTEM)
        self.systems.acted.connect(self.log_item)
        self.events = ActionsWidget(LogSource.EVENT)
        self.events.acted.connect(self.log_item)

        self.compass = Compass()
        self.compass_widget = QWidget()
        compass_layout = QHBoxLayout()
        self.compass_widget.setLayout(compass_layout)
        compass_layout.addWidget(self.compass)
        self.compass.angle_event.connect(self.log_item)

        self.exact_angle = ExactAngle()
        self.exact_angle_widget = QWidget()
        exact_angle_layout = QHBoxLayout()
        self.exact_angle_widget.setLayout(exact_angle_layout)
        exact_angle_layout.addWidget(self.exact_angle)
        self.exact_angle.btn_event.connect(self.reset_timer)
        self.exact_angle.angle_event.connect(self.log_item)

        tab_widget = QTabWidget()
        tab_bar = tab_widget.tabBar()
        tab_bar.setFont(QFont('Consolas', 12, 3))
        tab_widget.addTab(self.compass_widget, "Compass")
        tab_widget.addTab(self.exact_angle_widget, "Precise Angle")
        tab_widget.setStyleSheet("""
                QTabWidget::pane {
                    border-top: 2px solid #C2C7CB;
                }
                /* Style the tab using the tab sub-control. Note that
                    it reads QTabBar _not_ QTabWidget */
                QTabBar::tab {
                    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #E1E1E1, stop: 0.4 #DDDDDD,
                                stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3);
                    border: 2px solid #C4C4C3;
                    border-bottom-color: #C2C7CB; /* same as the pane color */
                    border-top-left-radius: 4px;
                    border-top-right-radius: 4px;
                    min-width: 8ex;
                    padding: 2px;
                    color: black;
                }

                QTabBar::tab:selected, QTabBar::tab:hover {
                    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                stop: 0 #fafafa, stop: 0.4 #f4f4f4,
                                stop: 0.5 #e7e7e7, stop: 1.0 #fafafa);
                }

                QTabBar::tab:selected {
                    border-color: #ff0000;
                    border-bottom-color: #C2C7CB; /* same as pane color */
                }

                QTabBar::tab:!selected {
                    margin-top: 2px; /* make non-selected tabs look smaller */
                }
            """)

        header_layout = QHBoxLayout()
        self.zulu_time_label = QLabel()
        self.assessor_label = QLabel()
        self.date_label = QLabel()
        self.dl_label = QLabel()
        self.mnemonic_label = QLabel()
        header_layout.addWidget(self.zulu_time_label)
        header_layout.addWidget(self.assessor_label)
        header_layout.addWidget(self.date_label)
        header_layout.addWidget(self.dl_label)
        header_layout.addWidget(self.mnemonic_label)
        res = QApplication.primaryScreen().size()
        w, h = res.width(), res.height()
        if w > 1920 or h > 1080:
            hdr_font = QFont("Consolas", 16, 2)
            end_font = QFont("Consolas", 32, 5)
        else:
            hdr_font = QFont("Consolas", 14, 2)
            end_font = QFont("Consolas", 28, 5)
        for index in range(header_layout.count()):
            widget = header_layout.itemAt(index).widget()
            widget.setSizePolicy(
                QSizePolicy.Preferred, QSizePolicy.Maximum
            )
            widget.setFont(hdr_font)
            widget.setAlignment(Qt.AlignCenter)

        # Setup logging state machine
        self.init_log_sm()

        # Setup splitters
        actions_splitter = QSplitter(
            Qt.Horizontal,
            frameShape=QFrame.StyledPanel,
            frameShadow=QFrame.Plain
        )
        actions_splitter.addWidget(self.systems)
        actions_splitter.addWidget(self.events)
        actions_splitter.addWidget(tab_widget)
        actions_splitter.setChildrenCollapsible(False)
        main_splitter = QSplitter(
            Qt.Vertical,
            frameShape=QFrame.StyledPanel,
            frameShadow=QFrame.Plain
        )
        self.log_area = QTableWidget(0, 3)
        self.log_area.cellDoubleClicked.connect(self.entry_inspected)
        self.log_area.cellChanged.connect(self.entry_changed)
        self.log_area.setHorizontalHeaderLabels(
            ["Time", "System", "Events"]
        )
        self.log_area.horizontalHeader().setStretchLastSection(True)
        self.set_dark_mode(dark_mode)
        end_msn_btn = QPushButton("END\r\nMISSION")
        end_msn_btn.clicked.connect(self.end_mission)
        end_msn_btn.setFont(end_font)
        end_msn_btn.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        end_msn_btn.setStyleSheet("background-color: red; color: white")
        bottom_layout = QGridLayout()
        bottom_widget = QWidget()
        bottom_widget.setLayout(bottom_layout)
        bottom_layout.addWidget(self.log_area, 0, 0, 1, 7)
        bottom_layout.addWidget(end_msn_btn, 0, 8, 1, 1)
        main_splitter.addWidget(actions_splitter)
        main_splitter.addWidget(bottom_widget)
        main_splitter.setChildrenCollapsible(False)
        handle_css = """
            QSplitter::handle {
                background-image: url(:/imgs/dot_pattern.png);
                background-repeat: repeat-xy;
                background-color: none;
                border: 1px solid gray;
            }
            QSplitter::handle:pressed {
                background-image: url(:/imgs/pressed.png);
            }
        """
        actions_splitter.setStyleSheet(handle_css)
        main_splitter.setStyleSheet(handle_css)

        # Finalize layout
        main_layout = QVBoxLayout()
        main_layout.addLayout(header_layout)
        main_layout.addWidget(main_splitter)
        self.setLayout(main_layout)
示例#28
0
class NeuralBoard(QWidget):
    def __init__(self, size, Parent=None):
        '''
        Constructor
        '''
        super().__init__(Parent)

        self.__InitData()  #先初始化數據,再初始化界面
        self.__InitView(size)

    def __InitData(self):

        self.__size = QSize(360, 560)

    def __InitView(self, size):
        #設置界面的尺寸爲__size
        self.setFixedSize(self.__size)
        self.board = QHBoxLayout(self)

        for layer_size in size:
            layer = self.addLayer()
            for neural_size in range(layer_size):
                self.addNeural(layer)

    def addNeural(self, layer):
        neural = QPushButton()
        #neural.setGeometry(-2, -2, 1, 1)
        neural.setMaximumSize(QSize(24, 24))
        #neural.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        neural.setStyleSheet(
            'background-color: rgb(0,0,255);border-radius:12; border:2px solid black'
        )
        layer.addWidget(neural)

    def addLayer(self):
        layer = QVBoxLayout(self)
        self.board.addLayout(layer)
        return layer

    def setActivate(self, layer, index, value):
        #self.clear()
        neural = self.getNeural((layer, index))
        color = str(int(value * 255))
        neural.setStyleSheet('background-color: rgb(' + color + ',' + color +
                             ',255); border-radius:12; border:2px solid black')

    def clear(self):
        layers = self.board.findChildren(QVBoxLayout)
        for layer in layers:
            for index in range(layer.count()):
                neural = layer.itemAt(index).widget()
                neural.setStyleSheet(
                    'background-color: rgb(0,0,255);border-radius:12; border:2px solid black'
                )

    def paintEvent(self, event):
        painter = QPainter(self)
        layers = self.board.findChildren(QVBoxLayout)
        for i in range(len(layers) - 1):
            layer1 = layers[i]
            layer2 = layers[i + 1]
            for j in range(layer1.count()):
                n1 = layer1.itemAt(j).widget()
                for k in range(layer2.count()):
                    n2 = layer2.itemAt(k).widget()
                    painter.setPen(Qt.gray)
                    painter.drawLine(
                        QLine(n1.pos().x() + 12,
                              n1.pos().y() + 12,
                              n2.pos().x() + 12,
                              n2.pos().y() + 12))

    def skeleton(self):
        layers = self.board.findChildren(QVBoxLayout)
        for layer in layers:
            for index in range(layer.count()):
                layer.itemAt(index).widget()

    def getNeural(self, n_index):
        [l_index, n_index] = n_index
        layer = self.board.itemAt(l_index)
        neural = layer.itemAt(n_index).widget()
        return neural
class Weijiejue(QDialog):

    def __init__(self,list,i,parent = None):
        super(Weijiejue,self).__init__(parent)
        #设置界面大小、名称、背景
        #self.resize(800,900)
        self.setWindowTitle('故障诊断专家系统')
        self.setStyleSheet("background-image:url(tubiao_meitu.jpg)")
        QApplication.setStyle("Fusion")
        font = QtGui.QFont('微软雅黑',20)
        font1 = QtGui.QFont('微软雅黑light', 15)
        #窗体属性


        self.i1=i
        self.list1=list

        #
        #查询self.list1[self.i1],得到cankaoziliao字符串,转换为列表
        db = pymysql.connect("localhost", "root", "123456", "expertsy", charset='utf8')
        cur=db.cursor()



        #self.ckzl= ["手册1.pdf","图片1.jpg"]

        vbj = QVBoxLayout()
        vbj.setAlignment(Qt.AlignCenter)
        vbj.setSpacing(50)

        self.hbj1=QHBoxLayout()
        hbj2=QHBoxLayout()
        #

        self.setWindowFlags(Qt.Widget)
        self.paichatishi = QLabel(self.list1[self.i1])
        self.paichatishi.setFont(font)

        sql = 'SELECT 参考资料 FROM 问题关联 WHERE 问题="%s"' % self.list1[self.i1]
        cur.execute(sql)
        string = cur.fetchone()
        print(string)
        if len(string)!=0:
            string0 = string[0]
            self.ckzl = string0.split(",")


            for fuzu in self.ckzl:
                self.title1= QPushButton(fuzu)
                self.title1.setStyleSheet('''
                    QPushButton{
                        border:none;
                        color:blue;
                        font-size:15px;
                        height:30px;
                        padding-left:5px;
                        padding-right:5px;
                        text-align:center;
                    }
                    QPushButton:hover{
                        color:black;
                        border:1px solid #F3F3F5;
                        border-radius:10px;
                        background:LightGray;
                    }
                ''')
                file_path= fuzu
                self.title1.clicked.connect(partial(self.lianjie))
                #title1.clicked.connect(lambda :self.lianjie(file_path))
                self.hbj1.addWidget(self.title1)


        self.jiejuebut=QPushButton("解决了")
        self.jiejuebut.setFont(font1)
        self.weijiejuebut = QPushButton("未解决")
        self.weijiejuebut.setFont(font1)
        self.weijiejuebut.clicked.connect(partial(self.tonext))
        self.jiejuebut.clicked.connect(partial(self.showjiejue))

        hbj2.addStretch(1)
        hbj2.addWidget(self.weijiejuebut)
        hbj2.addStretch(2)
        hbj2.addWidget(self.jiejuebut)
        hbj2.addStretch(1)

        vbj.addStretch(1)
        vbj.addWidget(self.paichatishi)
        vbj.addStretch(2)
        vbj.addLayout(self.hbj1)
        vbj.addStretch(2)
        vbj.addLayout(hbj2)
        vbj.addStretch(1)
        self.setLayout(vbj)

    def tonext(self):

        for i in reversed (range(self.hbj1.count())):

            self.hbj1.itemAt(i).widget().close()
            self.hbj1.takeAt(i)

        changdu=len(self.list1)
        self.i1=self.i1+1
        if self.i1+1<changdu:
            self.paichatishi.setText(self.list1[self.i1])
        if self.i1+1==changdu:
            self.paichatishi.setText(self.list1[self.i1])
            self.weijiejuebut.setText("已经是最后一条")
            self.weijiejuebut.setEnabled(False)

        db = pymysql.connect("localhost", "root", "123456", "expertsy", charset='utf8')
        cur = db.cursor()
        sql = 'SELECT 参考资料 FROM 问题关联 WHERE 问题="%s"' % self.list1[self.i1]
        cur.execute(sql)
        string = cur.fetchone()
        string0 = string[0]
        if not string0 is None:
            print("assa")
            self.ckzl = string0.split(",")
            for fuzu in self.ckzl:
                self.title1= QPushButton(fuzu)
                self.title1.setStyleSheet('''
                                QPushButton{
                                    border:none;
                                    color:blue;
                                    font-size:15px;
                                    height:30px;
                                    padding-left:5px;
                                    padding-right:5px;
                                    text-align:center;
                                }
                                QPushButton:hover{
                                    color:black;
                                    border:1px solid #F3F3F5;
                                    border-radius:10px;
                                    background:LightGray;
                                }
                            ''')
                self.title1.clicked.connect(partial(self.lianjie))
                #title1.clicked.connect(lambda :self.lianjie(file_path))
                self.hbj1.addWidget(self.title1)


    def showjiejue(self):
        self.w3=Jiejue()
        self.w3.show()

    def lianjie(self):
        sender=self.sender()
        os.startfile(sender.text())
class LibraryWidget(QWidget):
    def __init__(self, parent, item, link, list_widget, show_new=False):
        super(LibraryWidget, self).__init__(None)

        self.parent = parent
        self.item = item
        self.link = link
        self.list_widget = list_widget
        self.show_new = show_new
        self.observer = None
        self.build_info = None

        self.destroyed.connect(lambda: self._destroyed())
        self.setEnabled(False)

        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(2, 2, 2, 2)
        self.setLayout(self.layout)

        self.infoLabel = QLabel("Loading build information...")

        self.launchButton = QPushButton("Launch")
        self.launchButton.setMinimumWidth(75)
        self.launchButton.setProperty("CancelButton", True)

        self.layout.addWidget(self.launchButton)
        self.layout.addWidget(self.infoLabel, stretch=1)

        self.thread = BuildInfoReader(link)
        self.thread.finished.connect(self.draw)
        self.thread.start()

        self.item.setSizeHint(self.sizeHint())

    def draw(self, build_info):
        if build_info is None:
            self.infoLabel.setText(
                ("Build *{0}* is damaged!").format(Path(self.link).name))
            self.launchButton.setText("Delete")
            self.launchButton.clicked.connect(self.ask_remove_from_drive)
            self.setEnabled(True)
            return

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

        self.build_info = build_info
        self.branch = self.build_info.branch
        self.item.date = build_info.commit_time

        self.icon_favorite = QIcon(":resources/icons/favorite.svg")
        self.icon_fake = QIcon(":resources/icons/fake.svg")
        self.icon_delete = QIcon(":resources/icons/delete.svg")

        self.launchButton = QPushButton("Launch")
        self.launchButton.setMinimumWidth(75)
        self.launchButton.setProperty("LaunchButton", True)

        self.subversionLabel = QLabel()
        self.branchLabel = QLabel()
        self.commitTimeLabel = QLabel()
        self.buildHashLabel = QLabel()

        self.countButton = QPushButton("0")
        self.countButton.setEnabled(False)
        self.countButton.setProperty("Count", True)
        self.countButton.hide()
        self.countButton.setFixedSize(24, 24)

        self.widgetFavorite = QPushButton()
        self.widgetFavorite.setEnabled(False)
        self.widgetFavorite.setFixedSize(24, 24)
        self.widgetFavorite.setIcon(self.icon_fake)
        self.widgetFavorite.setProperty("Icon", True)

        self.layout.addWidget(self.launchButton)
        self.layout.addWidget(self.subversionLabel)
        self.layout.addWidget(self.branchLabel)
        self.layout.addWidget(self.commitTimeLabel)
        self.layout.addWidget(self.buildHashLabel)
        self.layout.addStretch()
        self.layout.addWidget(self.countButton)
        self.layout.addWidget(self.widgetFavorite)

        self.launchButton.clicked.connect(self.launch)
        self.subversionLabel.setText(self.build_info.subversion)

        if self.branch == 'lts':
            branch_name = "LTS"
        else:
            branch_name = self.branch.replace('-', ' ').title()

        self.branchLabel.setText(branch_name)

        self.commitTimeLabel.setText(self.build_info.commit_time)
        self.buildHashLabel.setText(self.build_info.build_hash)

        # Context menu
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.context_menu)

        self.menu = QMenu()
        self.menu.setFont(self.parent.font)

        self.menu_extended = QMenu()
        self.menu_extended.setFont(self.parent.font)

        self.deleteAction = QAction("Delete From Drive", self)
        self.deleteAction.setIcon(self.icon_delete)
        self.deleteAction.triggered.connect(self.ask_remove_from_drive)

        self.setAsFavoriteAction = QAction("Mark As Favorite", self)
        self.setAsFavoriteAction.setIcon(self.icon_favorite)
        self.setAsFavoriteAction.triggered.connect(self.set_favorite)

        self.registerExtentionAction = QAction("Register Extension")
        self.registerExtentionAction.triggered.connect(self.register_extension)

        self.createShortcutAction = QAction("Create Shortcut")
        self.createShortcutAction.triggered.connect(self.create_shortcut)

        self.showFolderAction = QAction("Show Folder")
        self.showFolderAction.triggered.connect(self.show_folder)

        self.createSymlinkAction = QAction("Create Symlink")
        self.createSymlinkAction.triggered.connect(self.create_symlink)

        self.menu.addAction(self.setAsFavoriteAction)

        if get_platform() == 'Windows':
            self.menu.addAction(self.registerExtentionAction)

        self.menu.addAction(self.createShortcutAction)
        self.menu.addAction(self.createSymlinkAction)
        self.menu.addAction(self.showFolderAction)
        self.menu.addAction(self.deleteAction)

        self.menu_extended.addAction(self.deleteAction)

        if self.show_new:
            self.NewItemLabel = QLabel("New")
            self.NewItemLabel.setAlignment(Qt.AlignRight | Qt.AlignCenter)
            self.NewItemLabel.setIndent(6)
            self.layout.addWidget(self.NewItemLabel)

            if get_mark_as_favorite() == 0:
                pass
            elif (get_mark_as_favorite() == 1 and self.branch == "stable"):
                self.set_favorite()
            elif (get_mark_as_favorite() == 2 and self.branch == "daily"):
                self.set_favorite()
            elif get_mark_as_favorite() == 3:
                self.set_favorite()
        elif get_favorite_path() == self.link:
            self.set_favorite()

        self.setEnabled(True)
        self.list_widget.sortItems()
        self.list_widget.resize_labels(
            ('subversionLabel', 'branchLabel',
             'commitTimeLabel', 'buildHashLabel'))

    def context_menu(self):
        if len(self.list_widget.selectedItems()) > 1:
            self.menu_extended.exec_(QCursor.pos())
            return

        link_path = Path(get_library_folder()) / "bl_symlink"
        link = link_path.as_posix()

        if os.path.exists(link):
            if (os.path.isdir(link) or os.path.islink(link)):
                if link_path.resolve() == self.link:
                    self.createSymlinkAction.setEnabled(False)
                    self.menu.exec_(QCursor.pos())
                    return

        self.createSymlinkAction.setEnabled(True)
        self.menu.exec_(QCursor.pos())

    def mouseDoubleClickEvent(self, event):
        if self.build_info is not None:
            self.launch()

    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            if hasattr(self, "NewItemLabel"):
                self.NewItemLabel.hide()

            mod = QApplication.keyboardModifiers()
            if not (mod == Qt.ShiftModifier or mod == Qt.ControlModifier):
                self.list_widget.clearSelection()
                self.item.setSelected(True)

            event.accept()

        event.ignore()

    @QtCore.pyqtSlot()
    def launch(self):
        self.item.setSelected(True)

        if hasattr(self, "NewItemLabel"):
            self.NewItemLabel.hide()

        platform = get_platform()
        library_folder = Path(get_library_folder())

        if platform == 'Windows':
            b3d_exe = library_folder / self.link / "blender.exe"
            proc = _popen(b3d_exe.as_posix())
        elif platform == 'Linux':
            b3d_exe = library_folder / self.link / "blender"
            proc = _popen('nohup "' + b3d_exe.as_posix() + '"')

        if self.observer is None:
            self.observer = Observer(self)
            self.observer.count_changed.connect(self.proc_count_changed)
            self.observer.started.connect(self.observer_started)
            self.observer.finished.connect(self.observer_finished)
            self.observer.start()

        self.observer.append_proc(proc)

    def proc_count_changed(self, count):
        self.countButton.setText(str(count))

    def observer_started(self):
        self.countButton.show()
        self.deleteAction.setEnabled(False)

    def observer_finished(self):
        self.observer = None
        self.countButton.hide()
        self.deleteAction.setEnabled(True)

    @QtCore.pyqtSlot()
    def ask_remove_from_drive(self):
        self.item.setSelected(True)
        self.dlg = DialogWindow(
            self.parent, title="Warning",
            text="Are you sure you want to<br>delete selected builds?",
            accept_text="Yes", cancel_text="No", icon=DialogIcon.WARNING)

        if len(self.list_widget.selectedItems()) > 1:
            self.dlg.accepted.connect(self.remove_from_drive_extended)
        else:
            self.dlg.accepted.connect(self.remove_from_drive)

    @QtCore.pyqtSlot()
    def remove_from_drive_extended(self):
        for item in self.list_widget.selectedItems():
            self.list_widget.itemWidget(item).remove_from_drive()

    @QtCore.pyqtSlot()
    def remove_from_drive(self):
        self.launchButton.setText("Deleting")
        self.setEnabled(False)
        self.item.setFlags(self.item.flags() & ~Qt.ItemIsSelectable)
        path = Path(get_library_folder()) / self.link
        self.remover = Remover(path)
        self.remover.finished.connect(self.remover_finished)
        self.remover.start()

    def remover_finished(self, code):
        if code == 0:
            self.parent.draw_from_cashed(self.build_info)
            self.list_widget.remove_item(self.item)
            return
        else:
            self.launchButton.setText("Launch")
            self.setEnabled(True)
            return

    @QtCore.pyqtSlot()
    def set_favorite(self):
        set_favorite_path(self.link)

        if self.parent.favorite is not None:
            self.parent.favorite.widgetFavorite.setIcon(self.icon_fake)
            self.parent.favorite.setAsFavoriteAction.setVisible(True)

        self.parent.favorite = self
        self.widgetFavorite.setIcon(self.icon_favorite)
        self.setAsFavoriteAction.setVisible(False)

    @QtCore.pyqtSlot()
    def register_extension(self):
        path = Path(get_library_folder()) / self.link
        self.register = Register(path)
        self.register.start()

    @QtCore.pyqtSlot()
    def create_shortcut(self):
        name = "Blender {0} {1}".format(
            self.build_info.subversion.replace('(', '').replace(')', ''),
            self.build_info.branch.replace('-', ' ').title())

        create_shortcut(self.link, name)

    @QtCore.pyqtSlot()
    def create_symlink(self):
        target = self.link.as_posix()
        link = (Path(get_library_folder()) / "bl_symlink").as_posix()
        platform = get_platform()

        if platform == 'Windows':
            if os.path.exists(link):
                if os.path.isdir(link):
                    os.rmdir(link)

            _check_call('mklink /J "{0}" "{1}"'.format(link, target))
        elif platform == 'Linux':
            if os.path.exists(link):
                if os.path.islink(link):
                    os.unlink(link)

            os.symlink(target, link)

    @QtCore.pyqtSlot()
    def show_folder(self):
        platform = get_platform()
        library_folder = Path(get_library_folder())
        folder = library_folder / self.link

        if platform == 'Windows':
            os.startfile(folder.as_posix())
        elif platform == 'Linux':
            subprocess.call(["xdg-open", folder.as_posix()])

    def _destroyed(self):
        if self.parent.favorite == self:
            self.parent.favorite = None
示例#31
0
class Calendar(QWidget):
    def __init__(self,
                 parent=None,
                 year=int(time.strftime('%Y', time.localtime(time.time()))),
                 month=int(time.strftime('%m', time.localtime(time.time())))):
        super().__init__(parent)

        # Set Schedule Layout Components ===============
        self.scheduleLayout = QVBoxLayout()
        # -------------------------------
        self.titleBox = QHBoxLayout()
        self.titleLabel = QLabel("title: ")
        self.titleLineEdit = QLineEdit()
        # -------------------------------
        self.placeBox = QHBoxLayout()
        self.placeLabel = QLabel("place: ")
        self.placeLineEdit = QLineEdit()
        # -------------------------------
        self.dateBox = QHBoxLayout()
        self.dateLabel = QLabel("time:")
        self.fromHour = QSpinBox()
        self.fromMin = QSpinBox()
        self.toHour = QSpinBox()
        self.toMin = QSpinBox()
        # -------------------------------
        self.discription = QHBoxLayout()
        self.contentLabel = QLabel("content: ")
        self.content = QTextEdit()
        # -------------------------------
        self.modifyBtn = Button("Modifying", self.modifying)
        # ==============================================

        self.displayCalendar = MyCalendar()
        self.startDay = 0
        self.maxDay = 0
        self.currentYear = year
        self.currentMonth = month
        self.currentDay = 0
        self.firstClick = True
        self.displayCalendar.loadHoliday()
        self.today = time.localtime()

        if os.name == 'nt':
            self.fileRoot = ".\schedules\schedules.txt"

        else:
            self.fileRoot = "./schedules/schedules.txt"

        try:
            scheduleFile = open(self.fileRoot, "rb")
            self.displayCalendar.schedule = pickle.load(scheduleFile)
            print(self.displayCalendar.schedule)

        except EOFError:
            pass

        # main layout
        self.mainLayout = QHBoxLayout()

        # Left side Layout ================================
        self.leftLayout = QVBoxLayout()

        # Stacked Widget Part -----------------------------
        # Setting Stacked Widget(like a switching Tabs)
        self.setSchedule = QWidget()
        self.lunaDate = QWidget()

        # Design And Setting Actions each Tab. if want to Append any action, plz input the action in here.
        self.setScheduleUI()
        self.lunaDateUI()

        # Appending tabs in Stack
        self.Stack = QStackedWidget()
        self.Stack.addWidget(self.setSchedule)
        self.Stack.addWidget(self.lunaDate)

        # Switching Button layout Design And binding button with action.
        self.tabLayout = QHBoxLayout()
        self.tabLayout.addWidget(Button("스케쥴러", lambda: self.display(0)))
        self.tabLayout.addWidget(Button("음력", lambda: self.display(1)))

        for i in range(self.tabLayout.count()):
            self.tabLayout.itemAt(i).widget().setStyleSheet('font-size: 8pt')

        self.leftLayout.addLayout(self.tabLayout)
        # -------------------------------------------------

        # handling Year & month ----------------------------------
        self.moveMonth = QHBoxLayout()

        self.previousBtn = Button("<", self.previousMonth)

        # showing Year and month using Combobox(Year range: 1980 ~ 2040, Month range: 1, 12)
        self.yearCombo = QComboBox()
        self.yearCombo.addItems([str(x) for x in range(1980, 2041)])
        self.yearCombo.setCurrentText(str(self.currentYear))

        self.monthCombo = QComboBox()
        self.monthCombo.addItems([str(x) for x in range(1, 13)])
        self.monthCombo.setCurrentText(str(self.currentMonth))

        self.nextBtn = Button(">", self.nextMonth)

        self.moveMonth.addStretch()
        self.moveMonth.addWidget(self.previousBtn)
        self.moveMonth.addWidget(self.yearCombo)
        self.moveMonth.addWidget(self.monthCombo)
        self.moveMonth.addWidget(self.nextBtn)
        self.moveMonth.addStretch()
        self.leftLayout.addLayout(self.moveMonth)
        self.leftLayout.addStretch()
        # -------------------------------------------------

        # Set Day of Week ---------------------------------
        self.weekDayLayout = QHBoxLayout()
        enumDays = ["일", "월", "화", "수", "목", "금", "토"]

        for i in enumDays:
            label = QLabel(i)
            label.setAlignment(Qt.AlignCenter)
            self.weekDayLayout.addWidget(label)

        self.leftLayout.addLayout(self.weekDayLayout)
        # -------------------------------------------------

        # grid layout to appending date Buttons
        self.calendarGrid = QGridLayout()
        self.calendarGrid.setSizeConstraint(QLayout.SetFixedSize)
        self.leftLayout.addLayout(self.calendarGrid)
        self.leftLayout.addStretch(7)

        # showing status
        self.statusLabel = QLabel("btn Status")
        self.leftLayout.addWidget(self.statusLabel)
        # ==================================================

        # Set grid
        self.displayCalendar.setCalander(self.currentYear, self.currentMonth)
        self.renderDate(self.displayCalendar.getCalander())

        # Set ComboBox Changing Event
        self.yearCombo.currentTextChanged.connect(
            lambda: self.selectionChanged())
        self.monthCombo.currentTextChanged.connect(
            lambda: self.selectionChanged())

        self.mainLayout.addLayout(self.leftLayout)
        self.mainLayout.addWidget(self.Stack)
        self.Stack.setCurrentIndex(0)  # default Tab -> set calendar
        self.setLayout(self.mainLayout)
        self.setWindowTitle("Calendar")

    def renderDate(self, newCalendar):
        # =========== Append Day Buttons ===============
        self.clearLayout(self.calendarGrid)
        todayYear = self.today.tm_year
        todayMonth = self.today.tm_mon
        todayDay = self.today.tm_mday
        toggle = True

        for i in newCalendar:
            print(i)

        # Enroll button
        for row, column in enumerate(newCalendar):
            for col, day in enumerate(column):
                btn = Button(str(day), self.btnEvent)

                # deactivate button condition
                if toggle:
                    if day != 1:
                        btn.setEnabled(False)

                    else:
                        toggle = False

                else:
                    if (row == len(newCalendar) - 1) and (day // 10 == 0):
                        btn.setEnabled(False)

                # set today button color
                if (self.currentYear, self.currentMonth,
                        day) == (todayYear, todayMonth, todayDay):
                    btn.setStyleSheet('font-style: italic;')

                # if this day have any event represent event
                key = '-'.join(
                    [str(self.currentYear),
                     str(self.currentMonth),
                     str(day)])
                if key in self.displayCalendar.schedule.keys(
                ) and btn.isEnabled():
                    btn.setStyleSheet('color: blue;')
                    btn.setStyleSheet('background-color: skyblue;')
                    btn.setToolTip(
                        self.displayCalendar.schedule[key].getTitle())

                for restMonth, restDay, title in self.displayCalendar.holidays:
                    if restMonth == self.currentMonth and restDay == day and btn.isEnabled(
                    ):
                        if key in self.displayCalendar.schedule.keys(
                        ) and btn.isEnabled():
                            btn.setStyleSheet(
                                'background-color: skyblue; color: red;')
                            btn.setToolTip(title)

                        else:
                            btn.setStyleSheet('color: red;')
                            btn.setToolTip(title)
                            break

                # 공휴일은 빨간색으로 설정해준다.
                if col == 0 and btn.isEnabled():
                    btn.setStyleSheet('color: red;')

                self.calendarGrid.addWidget(btn, row, col)
        # ===============================================
        self.displayCalendar.enrollHoliday(self.currentYear)
        self.displayCalendar.loadHoliday()

    def btnEvent(self):
        # self.showingWidget(self.scheduleLayout)

        self.setFixedSize(self.mainLayout.sizeHint())

        btn = self.sender()
        self.statusLabel.setText("Day: " + btn.text() + " is Clicked.")
        self.currentDay = btn.text()

        target = "-".join([
            str(self.currentYear),
            str(self.currentMonth),
            str(self.currentDay)
        ])
        targetEvent = self.displayCalendar.schedule.get(target)

        if not targetEvent:
            self.titleLineEdit.setText("None")
            self.placeLineEdit.clear()
            self.fromHour.setValue(0)
            self.fromMin.setValue(0)
            self.toHour.setValue(0)
            self.toMin.setValue(0)
            self.content.clear()

        else:
            self.titleLineEdit.setText(targetEvent.getTitle())
            self.placeLineEdit.setText(targetEvent.getPlace())

            timeSet = targetEvent.getDate().split(",")
            self.fromHour.setValue(int(timeSet[0]))
            self.fromMin.setValue(int(timeSet[1]))
            self.toHour.setValue(int(timeSet[2]))
            self.toMin.setValue(int(timeSet[3]))

            self.content.setText(targetEvent.getDescription())

    def modifying(self):
        newEvent = MyEvent()
        eventList = [
            self.titleLineEdit.text(),
            self.placeLineEdit.text(),
            ",".join([
                str(self.fromHour.value()),
                str(self.fromMin.value()),
                str(self.toHour.value()),
                str(self.toMin.value())
            ]),
            self.content.toPlainText(),
        ]

        newEvent.setEvent(*eventList)

        target = "-".join([
            str(self.currentYear),
            str(self.currentMonth),
            str(self.currentDay)
        ])
        self.displayCalendar.schedule[target] = newEvent
        self.statusLabel.setText("modified")

    # rendering previous month calendar
    def previousMonth(self):
        if self.currentMonth is 1:
            self.currentYear -= 1
            self.yearCombo.setCurrentText(str(self.currentYear))
            self.currentMonth = 12
            self.monthCombo.setCurrentText(str(self.currentMonth))

        else:
            self.currentMonth -= 1
            self.monthCombo.setCurrentText(str(self.currentMonth))

    # rendering next month calendar
    def nextMonth(self):
        if self.currentMonth is 12:
            self.currentYear += 1
            self.yearCombo.setCurrentText(str(self.currentYear))
            self.currentMonth = 1
            self.monthCombo.setCurrentText(str(self.currentMonth))
        else:
            self.currentMonth += 1
            self.monthCombo.setCurrentText(str(self.currentMonth))

    def selectionChanged(self):
        self.currentYear = int(self.yearCombo.currentText())
        self.currentMonth = int(self.monthCombo.currentText())

        self.displayCalendar.setYear(self.currentYear)
        self.displayCalendar.setMonth(self.currentMonth)
        self.displayCalendar.setCalander(self.currentYear, self.currentMonth)
        self.renderDate(self.displayCalendar.getCalander())

    def clearLayout(self, layout):
        while layout.count():
            child = layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()

    def closeEvent(self, event):
        keys = []
        myEvent = self.displayCalendar.schedule

        for target in myEvent.keys():
            title = myEvent[target].title
            place = myEvent[target].place

            description = myEvent[target].description

            if (title, place, description) == ('', '', ''):
                keys.append(target)

        for target in keys:
            del self.displayCalendar.schedule[target]

        with open(self.fileRoot, "wb") as file:
            pickle.dump(self.displayCalendar.schedule, file)

    def setScheduleUI(self):
        # Schedules layout ==================================
        self.titleBox.addWidget(self.titleLabel)
        self.titleBox.addWidget(self.titleLineEdit)

        self.placeBox.addWidget(self.placeLabel)
        self.placeBox.addWidget(self.placeLineEdit)

        self.fromHour.setRange(0, 24)
        self.toHour.setRange(0, 24)
        self.fromMin.setRange(0, 59)
        self.toMin.setRange(0, 59)

        self.fromHour.valueChanged.connect(
            lambda: self.toHour.setRange(self.fromHour.value(), 24))
        # self.toHour.valueChanged.connect(lambda: self.fromHour.setRange(0, self.toHour.value()))

        self.fromMin.valueChanged.connect(
            lambda: self.toMin.setRange(self.fromMin.value(), 59))
        # self.toMin.valueChanged.connect(lambda: self.fromMin.setRange(0, self.toMin.value()))

        self.dateBox.addWidget(self.dateLabel)
        self.dateBox.addWidget(self.fromHour)
        self.dateBox.addWidget(self.fromMin)
        self.dateBox.addWidget(QLabel("    ~ "))
        self.dateBox.addWidget(self.toHour)
        self.dateBox.addWidget(self.toMin)

        self.contentLabel.setAlignment(Qt.AlignTop)
        self.discription.addWidget(self.contentLabel)
        self.discription.addWidget(self.content)

        self.scheduleLayout.addLayout(self.titleBox)
        self.scheduleLayout.addLayout(self.placeBox)
        self.scheduleLayout.addLayout(self.dateBox)
        self.scheduleLayout.addLayout(self.discription)
        # modifying schedule Button
        self.scheduleLayout.addWidget(self.modifyBtn)
        self.setSchedule.setLayout(self.scheduleLayout)

    def lunaDateUI(self):
        month_31 = [1, 3, 5, 7, 8, 10, 12]

        layout = QVBoxLayout()
        #layout.addWidget(QLabel("Luna Date"))
        topLayout = QHBoxLayout()
        self.yearSpinner = QSpinBox()
        self.yearSpinner.setRange(1980, 2040)
        self.monthSpinner = QSpinBox()
        self.monthSpinner.setRange(1, 12)
        self.daySpinner = QSpinBox()

        self.yearSpinner.setValue(self.today.tm_year)
        self.monthSpinner.setValue(self.today.tm_mon)
        self.daySpinner.setValue(self.today.tm_mday)

        self.monthSpinner.valueChanged.connect(
            lambda: self.daySpinner.setRange(
                1,
                self.displayCalendar.getMaxday(self.yearSpinner.value(),
                                               self.monthSpinner.value())))

        self.modeComboBox = QComboBox()
        self.modeComboBox.addItems(["양력 -> 음력", "음력 -> 양력"])
        convertBtn = Button("convert", self.lunarBtnEvent)
        resetBtn = Button("reset", self.lunarBtnEvent)

        bottomLayout = QVBoxLayout()
        titleBox = QHBoxLayout()
        solarBox = QHBoxLayout()
        lunarBox = QHBoxLayout()
        self.todayLabel = QLabel("오늘의 날짜정보")
        self.todayLabel.setStyleSheet('color: red; font-size: 18px;')
        solarLabel = QLabel("양력날짜")
        solarLabel.setStyleSheet('color: gray;')
        todaySolarDay = "%04d-%02d-%02d" % (
            self.today.tm_year, self.today.tm_mon, self.today.tm_mday)
        self.solarDateLabel = QLabel(todaySolarDay)
        lunarLabel = QLabel("음력날짜")
        lunarLabel.setStyleSheet('color: gray;')
        self.lunarDateLabel = QLabel(
            self.displayCalendar.calculator.getToLunarDate(
                self.today.tm_year, self.today.tm_mon, self.today.tm_mday))

        titleBox.addWidget(self.todayLabel)
        solarBox.addWidget(solarLabel)
        solarBox.addWidget(self.solarDateLabel)
        lunarBox.addWidget(lunarLabel)
        lunarBox.addWidget(self.lunarDateLabel)
        bottomLayout.addLayout(titleBox)
        bottomLayout.addLayout(solarBox)
        bottomLayout.addLayout(lunarBox)

        topLayout.addWidget(self.yearSpinner)
        topLayout.addWidget(self.monthSpinner)
        topLayout.addWidget(self.daySpinner)
        topLayout.addWidget(self.modeComboBox)
        topLayout.addWidget(convertBtn)
        topLayout.addWidget(resetBtn)

        layout.addStretch()
        layout.addLayout(bottomLayout)
        layout.addLayout(topLayout)
        layout.addStretch()
        self.lunaDate.setLayout(layout)

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

    def hidingWidget(self, layout):
        for i in range(layout.count()):
            item = layout.itemAt(i)

            if item.widget() is not None:
                layout.itemAt(i).widget().hide()

            elif item.layout() is not None:
                self.hidingWidget(layout.itemAt(i).layout())

    def showingWidget(self, layout):
        for i in range(layout.count()):
            item = layout.itemAt(i)
            if item.widget() is not None:
                layout.itemAt(i).widget().show()
            elif item.layout() is not None:
                self.showingWidget(layout.itemAt(i).layout())

    def lunarBtnEvent(self):
        btn = self.sender()
        key = btn.text()

        if key == 'reset':
            self.todayLabel.setText('오늘의 날짜정보')
            self.todayLabel.setStyleSheet('color: red; font-size: 18px;')

        elif key == 'convert':
            if self.modeComboBox.currentIndex() is 0:
                self.todayLabel.setText("양력 {}년 {}월 {}일".format(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value()))
                self.todayLabel.setStyleSheet(
                    'font-weight: bold; color: black; font-size: 12px;')
                lunarDate = self.displayCalendar.calculator.getToLunarDate(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value())
                self.solarDateLabel.setText(
                    str(self.yearSpinner.value()) + "-" +
                    str(self.monthSpinner.value()) + "-" +
                    str(self.daySpinner.value()))
                self.lunarDateLabel.setText(lunarDate)
            else:
                self.todayLabel.setText("음력 {}년 {}월 {}일".format(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value()))
                self.todayLabel.setStyleSheet(
                    'font-weight: bold; color: black; font-size: 12px;')
                solarDate = self.displayCalendar.calculator.toSolarDate(
                    self.yearSpinner.value(), self.monthSpinner.value(),
                    self.daySpinner.value())
                self.solarDateLabel.setText(
                    str(solarDate[0]) + "-" + str(solarDate[1]) + "-" +
                    str(solarDate[2]))
                self.lunarDateLabel.setText(
                    str(self.yearSpinner.value()) + "-" +
                    str(self.monthSpinner.value()) + "-" +
                    str(self.daySpinner.value()))
示例#32
0
class Ui_Widget(object):
    """ Klasa definiująca GUI """
    def setupUi(self, Widget):

        # widgety rysujące kształty, instancje klasy Ksztalt
        self.ksztalt1 = Ksztalt(self, Ksztalty.Polygon)
        self.ksztalt2 = Ksztalt(self, Ksztalty.Ellipse)
        self.ksztaltAktywny = self.ksztalt1

        # przyciski CheckBox ###
        uklad = QVBoxLayout()  # układ pionowy
        self.grupaChk = QButtonGroup()
        for i, v in enumerate(('Kwadrat', 'Koło', 'Trójkąt', 'Linia')):
            self.chk = QCheckBox(v)
            self.grupaChk.addButton(self.chk, i)
            uklad.addWidget(self.chk)
        self.grupaChk.buttons()[self.ksztaltAktywny.ksztalt].setChecked(True)
        # CheckBox do wyboru aktywnego kształtu
        self.ksztaltChk = QCheckBox('<=')
        self.ksztaltChk.setChecked(True)
        uklad.addWidget(self.ksztaltChk)

        # układ poziomy dla kształtów oraz przycisków CheckBox
        ukladH1 = QHBoxLayout()
        ukladH1.addWidget(self.ksztalt1)
        ukladH1.addLayout(uklad)
        ukladH1.addWidget(self.ksztalt2)
        # koniec CheckBox ###

        # Slider i LCDNumber ###
        self.suwak = QSlider(Qt.Horizontal)
        self.suwak.setMinimum(0)
        self.suwak.setMaximum(255)
        self.lcd = QLCDNumber()
        self.lcd.setSegmentStyle(QLCDNumber.Flat)
        # układ poziomy (splitter) dla slajdera i lcd
        ukladH2 = QSplitter(Qt.Horizontal, self)
        ukladH2.addWidget(self.suwak)
        ukladH2.addWidget(self.lcd)
        ukladH2.setSizes((125, 75))

        # przyciski RadioButton ###
        self.ukladR = QHBoxLayout()
        for v in ('R', 'G', 'B'):
            self.radio = QRadioButton(v)
            self.ukladR.addWidget(self.radio)
        self.ukladR.itemAt(0).widget().setChecked(True)
        # grupujemy przyciski
        self.grupaRBtn = QGroupBox('Opcje RGB')
        self.grupaRBtn.setLayout(self.ukladR)
        self.grupaRBtn.setObjectName('Radio')
        self.grupaRBtn.setCheckable(True)
        # układ poziomy dla grupy Radio
        ukladH3 = QHBoxLayout()
        ukladH3.addWidget(self.grupaRBtn)
        # koniec RadioButton ###

        # Lista ComboBox i SpinBox ###
        self.listaRGB = QComboBox(self)
        for v in ('R', 'G', 'B'):
            self.listaRGB.addItem(v)
        self.listaRGB.setEnabled(False)
        # SpinBox
        self.spinRGB = QSpinBox()
        self.spinRGB.setMinimum(0)
        self.spinRGB.setMaximum(255)
        self.spinRGB.setEnabled(False)
        # układ pionowy dla ComboBox i SpinBox
        uklad = QVBoxLayout()
        uklad.addWidget(self.listaRGB)
        uklad.addWidget(self.spinRGB)
        # do układu poziomego grupy Radio dodajemy układ ComboBox i SpinBox
        ukladH3.insertSpacing(1, 25)
        ukladH3.addLayout(uklad)
        # koniec ComboBox i SpinBox ###

        # przyciski PushButton ###
        uklad = QHBoxLayout()
        self.grupaP = QButtonGroup()
        self.grupaP.setExclusive(False)
        for v in ('R', 'G', 'B'):
            self.btn = QPushButton(v)
            self.btn.setCheckable(True)
            self.grupaP.addButton(self.btn)
            uklad.addWidget(self.btn)
        # grupujemy przyciski
        self.grupaPBtn = QGroupBox('Przyciski RGB')
        self.grupaPBtn.setLayout(uklad)
        self.grupaPBtn.setObjectName('Push')
        self.grupaPBtn.setCheckable(True)
        self.grupaPBtn.setChecked(False)
        # koniec PushButton ###

        # etykiety QLabel i pola QLineEdit ###
        ukladH4 = QHBoxLayout()
        self.labelR = QLabel('R')
        self.labelG = QLabel('G')
        self.labelB = QLabel('B')
        self.kolorR = QLineEdit('0')
        self.kolorG = QLineEdit('0')
        self.kolorB = QLineEdit('0')
        for v in ('R', 'G', 'B'):
            label = getattr(self, 'label' + v)
            kolor = getattr(self, 'kolor' + v)
            ukladH4.addWidget(label)
            ukladH4.addWidget(kolor)
            kolor.setMaxLength(3)
        # koniec QLabel i QLineEdit ###

        # główny układ okna, wertykalny ###
        ukladOkna = QVBoxLayout()
        ukladOkna.addLayout(ukladH1)
        ukladOkna.addWidget(ukladH2)
        ukladOkna.addLayout(ukladH3)
        ukladOkna.addWidget(self.grupaPBtn)
        ukladOkna.addLayout(ukladH4)

        self.setLayout(ukladOkna)  # przypisanie układu do okna głównego
        self.setWindowTitle('Widżety')
        self.resize(200, 250)
示例#33
0
class CPinUI(QWidget):
    def __init__(self, pinID, parent=None):
        super(CPinUI, self).__init__(parent)
        self.m_PinID = pinID
        self.m_NodeID = interface.GetNodeIDByPinID(pinID)
        self.m_GraphicID = interface.GetGraphicIDByNodeID(self.m_NodeID)
        self.m_Btn = None
        self.m_Label = None
        self.m_HLayout = None
        self.m_DefaultWidget = None  # 默认值控件
        self._InitUI()
        self.SetIcon()
        self.SetText()
        self.ShowDefaultWidget()
        GetUIMgr().AddPinUI(pinID, self)

    def __del__(self):
        GetUIMgr().DelPinUI(self.m_PinID)

    def _InitUI(self):
        hBox = QHBoxLayout(self)
        hBox.setContentsMargins(0, 0, 0, 0)
        hBox.setSpacing(6)
        self.m_Btn = CTypeButton(self.m_PinID, self)
        self.m_Label = QLabel(self)
        self.m_HLayout = QHBoxLayout()
        self.m_HLayout.setContentsMargins(0, 0, 0, 0)
        self.m_HLayout.setSpacing(6)
        hBox.addWidget(self.m_Btn)
        hBox.addWidget(self.m_Label)
        hBox.addLayout(self.m_HLayout)

    def contextMenuEvent(self, event):
        super(CPinUI, self).contextMenuEvent(event)
        lstLineID = interface.GetAllLineByPin(self.m_PinID)
        menu = QMenu()
        for lineID in lstLineID:
            oPinID = interface.GetLineOtherPin(lineID, self.m_PinID)
            sPinDisplayName = interface.GetPinAttr(oPinID, bddefine.PinAttrName.DISPLAYNAME)
            nodeID = interface.GetNodeIDByPinID(oPinID)
            sNodeDisplayName = interface.GetNodeAttr(nodeID, bddefine.NodeAttrName.DISPLAYNAME)
            sMsg = "删除与\"%s\"-\"%s\"的连线" % (sNodeDisplayName, sPinDisplayName)
            func = functor.Functor(interface.DelLine, lineID)
            menu.addAction(sMsg, func)
        menu.exec_(QCursor.pos())
        event.accept()

    def SetIcon(self, iDataType=None):
        if iDataType is None:
            iPinType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.PIN_TYPE)
            if bddefine.PinIsFlow(iPinType):
                iDataType = -1
            else:
                iDataType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DATA_TYPE)
        icon = QIcon()
        pix = ":/icon/btn_%s.png" % iDataType
        icon.addPixmap(QPixmap(pix), QIcon.Normal, QIcon.Off)
        self.m_Btn.setIcon(icon)

    def SetText(self, sText=None):
        if sText is None:
            sText = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DISPLAYNAME)
        self.m_Label.setText(sText)

    def ShowDefaultWidget(self):
        iPinType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.PIN_TYPE)
        if iPinType != bddefine.PIN_INPUT_DATA_TYPE:
            return
        lstLine = interface.GetAllLineByPin(self.m_PinID)
        if lstLine:
            return
        oWidget = None
        iDataTye = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DATA_TYPE)
        if iDataTye in (bddefine.Type.INT, bddefine.Type.FLOAT, bddefine.Type.STR):
            oWidget = subpinui.CValidatorLineEdit(self.m_PinID, iDataTye)
        elif iDataTye == bddefine.Type.BOOL:
            oWidget = subpinui.CCheckBox(self.m_PinID)
        elif iDataTye == bddefine.Type.ENUM:
            oWidget = subpinui.CEnum(self.m_PinID)
        elif iDataTye == bddefine.Type.VECTOR3:
            oWidget = subpinui.CVector3(self.m_PinID)
        elif iDataTye == bddefine.Type.CHECKBOX:
            oWidget = subpinui.CComCheckBox(self.m_PinID)
        if oWidget:
            self.m_HLayout.addWidget(oWidget)
            self.m_DefaultWidget = oWidget
            self.adjustSize()

    def HideDefaultWidget(self):
        if not self.m_DefaultWidget:
            return
        self.m_DefaultWidget.setParent(None)
        index = self.m_HLayout.indexOf(self.m_DefaultWidget)
        item = self.m_HLayout.itemAt(index)
        self.m_HLayout.removeWidget(self.m_DefaultWidget)
        self.m_HLayout.removeItem(item)
        self.m_DefaultWidget = None
        self.adjustSize()

    def enterEvent(self, event):
        super(CPinUI, self).enterEvent(event)
        GetSignal().UI_LINE_CONNECT.emit(self.m_GraphicID, self.m_PinID)
        event.accept()
示例#34
0
class SimMoveDemo(QWidget):
    menuSignal = pyqtSignal(int)

    def __init__(self, parent):
        super().__init__(parent)

        self.parent = parent
        self.menuSignal.connect(self.addPlayers)
        self.currentAmp = AMPLITUDE
        self.startingBallSize = MINBALLSIZE * 2 + 1
        self.setGeometry(600, 200, WINDOWWIDTH, WINDOWHEIGHT)
        self.players = []
        self.bonuses = []
        self.cupPlayers = []
        self.cupMode = False
        self.finalGame = False
        self.balls = [Ball(self, self.startingBallSize)]
        self.key_notifier = KeyNotifier()
        self.key_notifier.key_signal.connect(self.__update_position__)
        self.key_notifier.start()
        self.stopOnStart = True
        self.finishCup = False
        self.playerLen = None
        self.previousBalls = len(self.balls)
        self.currentLevel = 1
        self.currentBall = 0
        self.semiFinalEnd = False
        self.weaponObj = None
        self.weaponObj2 = None
        self.deadPoints = []
        self.finalist1points = 0
        self.finalist2points = 0
        self.finalist1 = ''
        self.finalist2 = ''

    def addPlayers(self, option):
        if option == 1:
            self.players = [Player(self, 'player1', 1)]
        elif option == 2:
            self.players = [
                Player(self, 'player1', 2),
                Player(self, 'player2', 2)
            ]
        elif option == 4:
            self.players = [
                Player(self, 'player1', 2),
                Player(self, 'player2', 2)
            ]
            self.cupMode = True

        self.__init_ui__()
        self.timer = QBasicTimer()
        self.timer.start(20, self)

    def initPlayersAndBalls(self):
        for player in self.players:
            player.player.setPixmap(player.PixMap)
            player.player.setGeometry(player.PositionX, player.PositionY,
                                      player.Width, player.Heigth)
            player.weapon.weapon.setPixmap(player.weapon.PixMap)
            player.weapon.weapon.setGeometry(0, WINDOWHEIGHT - 87, WINDOWWIDTH,
                                             0)
            player.livesSignal.connect(self.updateLives)
            player.pointsSignal.connect(self.updatePoints)
        if self.cupMode:
            self.weaponObj = self.players[0].weapon
            self.weaponObj2 = self.players[1].weapon
        for ball in self.balls:
            ball.ball.setPixmap(ball.pixMapScaled)
            ball.ball.setGeometry(ball.x, ball.y, ball.size, ball.size)
        for p in self.players:
            p.show()

    def __init_ui__(self):
        self.initPlayersAndBalls()
        self.setWindowTitle('Bubble Trouble')
        self.stopOnStart = True
        # BACKGROUND
        oImage = QImage(IMAGES_DIR + 'background.png')
        sImage = oImage.scaled(QSize(WINDOWWIDTH, WINDOWHEIGHT))
        palette = QPalette()
        palette.setBrush(10, QBrush(sImage))
        self.setFocus()
        self.parent.setPalette(palette)
        self.setWindowFlags(Qt.WindowCloseButtonHint
                            | Qt.WindowMinimizeButtonHint)

        # elements
        self.livesPic1 = QPixmap(IMAGES_DIR + 'player1.png').scaled(20, 30)
        self.livesPic2 = QPixmap(IMAGES_DIR + 'player2.png').scaled(20, 30)

        verticalPlayerInf = QVBoxLayout()
        self.horizontalBox = QHBoxLayout()

        self.labelLives = []
        for player in self.players:
            self.labelLives.append(
                self.initPlayerLives(
                    QPixmap(IMAGES_DIR + player.playerId + '.png').scaled(
                        20, 30), player.lifes))

        for label in self.labelLives[0]:
            self.horizontalBox.addWidget(label, 1, Qt.AlignLeft | Qt.AlignTop)

        if len(self.players) > 1:
            self.horizontalBox.addSpacing(WINDOWWIDTH - 2 * 80 - 75)
            for label in self.labelLives[1]:
                self.horizontalBox.addWidget(label, 1,
                                             Qt.AlignRight | Qt.AlignTop)
        else:
            self.horizontalBox.addSpacing(WINDOWWIDTH - 150)

        self.initGuiElements(self.horizontalBox, verticalPlayerInf)

        self.setLayout(verticalPlayerInf)

    def initPlayerLives(self, pixMap, currentLives):
        labelLives = []
        for i in range(currentLives):
            labelLives.append(QLabel())
            labelLives[i].setPixmap(pixMap)
        return labelLives

    def updatePlayerPixMapLives(self, pixMap, currentLives, playerUpdated):
        if playerUpdated.playerId == 'player1':
            self.labelLives[0][currentLives].clear()
        elif playerUpdated.playerId == 'player2':
            self.labelLives[1][-currentLives - 1].clear()

    def resetPlayerPixMapLives(self, initLives):
        for x in range(2 * initLives + 1):
            if x != initLives:
                widget = self.horizontalBox.itemAt(x).widget()
            if x < initLives:
                widget.setPixmap(
                    QPixmap(IMAGES_DIR + 'player1.png').scaled(20, 30))
            elif x > initLives:
                widget.setPixmap(
                    QPixmap(IMAGES_DIR + 'player2.png').scaled(20, 30))

    def initGuiElements(self, horizontalBox, verticalPlayerInf):
        self.getReadyLabel = QLabel()
        self.getReadyLabel.setText('Get Ready!')
        self.getReadyLabel.setFont(
            QFont('Denne Kitten Heels', 30, QFont.ExtraBold))
        self.getReadyLabel.setAlignment(Qt.AlignTop)
        self.getReadyLabel.setFrameStyle(1)
        self.getReadyLabel.setStyleSheet(
            "QLabel{ background-color:rgba(81, 109, 131, 0.4) ;color:#D9C91B ;border-width:1px; border-style:solid;}"
        )

        self.player11LabelTxt = 'PLAYER 1'
        self.player1Tag = QLabel()
        self.player1Tag.setText(self.player11LabelTxt)
        self.player1Tag.setFont(
            QFont('Denne Kitten Heels', 18, QFont.ExtraBold))
        self.player1Tag.setAlignment(Qt.AlignLeft)
        self.player1Tag.setFrameStyle(33)
        self.player1Tag.setMidLineWidth(1)
        self.player1Tag.setStyleSheet(
            "QLabel{background-color: #CECECE; color:#E20000;}")
        self.player1Tag.setFixedSize(QSize(130, 31))

        self.player2LabelTxt = 'PLAYER 2'
        self.player2Tag = QLabel()
        self.player2Tag.setText(self.player2LabelTxt)
        self.player2Tag.setFont(
            QFont('Denne Kitten Heels', 18, QFont.ExtraBold))
        self.player2Tag.setAlignment(Qt.AlignLeft)
        self.player2Tag.setFrameStyle(33)
        self.player2Tag.setMidLineWidth(1)
        self.player2Tag.setStyleSheet(
            "QLabel{background-color: #CECECE; color:#265EBB;}")
        self.player2Tag.setFixedSize(QSize(130, 31))

        player1Points = '0'
        self.player1PointsTag = QLabel()
        self.player1PointsTag.setText(player1Points)
        self.player1PointsTag.setFont(QFont('kristen itc', 17,
                                            QFont.ExtraBold))
        self.player1PointsTag.setAlignment(Qt.AlignRight)
        self.player1PointsTag.setFrameStyle(33)
        self.player1PointsTag.setMidLineWidth(1)
        self.player1PointsTag.setStyleSheet(
            "QLabel{background-color: #CECECE; color:#676769;}")
        self.player1PointsTag.setFixedSize(QSize(100, 31))

        player2Points = '0'
        self.player2PointsTag = QLabel()
        self.player2PointsTag.setText(player2Points)
        self.player2PointsTag.setFont(QFont('kristen itc', 17,
                                            QFont.ExtraBold))
        self.player2PointsTag.setAlignment(Qt.AlignRight)
        self.player2PointsTag.setFrameStyle(33)
        self.player2PointsTag.setMidLineWidth(1)
        self.player2PointsTag.setStyleSheet(
            "QLabel{background-color: #CECECE; color:#676769;}")
        self.player2PointsTag.setFixedSize(QSize(100, 31))

        levelText = 'Level'
        levelTag = QLabel()
        levelTag.setText(levelText)
        levelTag.setFont(QFont('denne kitten heels', 17, QFont.ExtraBold))
        levelTag.setAlignment(Qt.AlignCenter)
        levelTag.setFrameStyle(33)
        levelTag.setMidLineWidth(1)
        levelTag.setStyleSheet(
            "QLabel{background-color: #CECECE; color:#C7820D;}")
        levelTag.setFixedSize(QSize(100, 31))

        self.levelNum = str(self.currentLevel)
        self.levelNumTag = QLabel()
        self.levelNumTag.setText(self.levelNum)
        self.levelNumTag.setFont(
            QFont('denne kitten heels', 17, QFont.ExtraBold))
        self.levelNumTag.setAlignment(Qt.AlignCenter)
        self.levelNumTag.setStyleSheet(
            "QLabel{background-color: #CECECE; color:#E20000;}")
        self.levelNumTag.setFixedSize(QSize(50, 31))

        horizontalBox.setContentsMargins(20, 0, 20, 0)

        verticalLevel = QVBoxLayout()
        verticalLevel.addWidget(levelTag)
        verticalLevel.addSpacing(-9)
        verticalLevel.addWidget(self.levelNumTag, 0, Qt.AlignCenter)

        horizontalPlayerInf = QHBoxLayout()
        horizontalPlayerInf.addWidget(self.player1Tag)
        horizontalPlayerInf.addWidget(self.player1PointsTag)
        horizontalPlayerInf.addSpacing(90)
        horizontalPlayerInf.addLayout(verticalLevel)
        horizontalPlayerInf.addSpacing(82)
        horizontalPlayerInf.addWidget(self.player2PointsTag)
        horizontalPlayerInf.addWidget(self.player2Tag)

        horizontalPlayerInf.setAlignment(Qt.AlignBottom)
        horizontalPlayerInf.setContentsMargins(10, 0, 10, 0)
        verticalPlayerInf.addLayout(horizontalBox)
        verticalPlayerInf.addWidget(self.getReadyLabel, 1,
                                    Qt.AlignCenter | Qt.AlignTop)
        verticalPlayerInf.addLayout(horizontalPlayerInf)

    def keyPressEvent(self, event):
        self.key_notifier.add_key(event.key())

    def keyReleaseEvent(self, event):
        self.key_notifier.rem_key(event.key())
        if not event.isAutoRepeat():
            for player in self.players:
                player.drawPlayer('normal')

    def __update_position__(self, key):
        for player in self.players:
            player.update(key)

    def closeEvent(self, event):
        self.key_notifier.die()

    def timerEvent(self, event):
        for ball in self.balls:
            if self.stopOnStart:
                time.sleep(2)
                self.getReadyLabel.close()
            ball.start()
            self.stopOnStart = False
        for bonus in self.bonuses:
            bonus.update()
            bonus.bonus.setPixmap(bonus.pixMapScaled)
            bonus.bonus.setGeometry(bonus.posX, bonus.posY, 30, 30)
            bonus.bonus.show()
        self.checkCollisionWeapon()
        self.checkCollisionPlayer()

    def splitBall(self, size, x, y):
        if size / 2 <= MINBALLSIZE:
            if len(self.balls) == 0:
                self.timer.stop()
                time.sleep(1)
                self.loadNextLevel()
        else:

            ball1 = Ball(self, size / 2)
            ball2 = Ball(self, size / 2)

            self.setBallProperties(ball1, x, y, True)
            self.setBallProperties(ball2, x, y, False)

            self.balls.append(ball1)
            self.balls.append(ball2)

            if random.randrange(BONUS_RANGE) == 0:
                bonus_type = random.choice(bonus_types)
                bonus = Bonus(self, bonus_type, x, y)
                bonus.isActive = True
                self.bonuses.append(bonus)

            ball1.splitedLeft = True
            ball2.splitedRight = True
            ball1.splitedCounter = 42
            ball2.splitedCounter = 42
            ball1.y = ball1.dy
            ball2.y = ball2.dy
            ball1.ball.show()
            ball2.ball.show()

    def setBallProperties(self, ball, x, y, isForward):
        ball.counter = x
        ball.dy = y
        ball.forward = isForward
        ball.ball.setPixmap(ball.pixMapScaled)
        ball.ball.setGeometry(ball.counter, ball.dy, ball.size, ball.size)

    def checkCollisionWeapon(self):
        for player in self.players:
            if player.weapon.isActive:
                for ball in self.balls:
                    if ball.counter <= player.weapon.posX and ball.counter + ball.size >= player.weapon.posX:
                        if ball.dy + ball.size >= player.weapon.posY:
                            player.weapon.isActive = False
                            size = ball.size
                            x = ball.counter
                            y = ball.dy
                            self.balls.remove(ball)
                            ball.ball.hide()
                            del ball

                            self.splitBall(size, x, y)
                            player.pointsSignal.emit(50)
                            break  # unisti samo jednu lopticu i izadji (pravi bag ako se izostavi -> unistava
                            # novonastale lopte)

    def checkCollisionPlayer(self):
        for player in self.players:
            for ball in self.balls:
                if player.PositionY <= ball.dy + ball.size - 20:
                    if(ball.counter <= player.PositionX and player.PositionX <= ball.counter + ball.size) or \
                     (ball.counter <= player.PositionX + 25 and player.PositionX + 25 <= ball.counter + ball.size) or \
                     (ball.counter <= player.PositionX and ball.counter + ball.size >= player.PositionX + 28) or \
                     (ball.counter >= player.PositionX and ball.counter + ball.size <= player.PositionX + 40):
                        self.timer.stop()
                        ball.ball.hide()
                        self.balls.remove(ball)

                        self.resetLevel()
                        player.livesSignal.emit()
            for bonus in self.bonuses:
                if (player.PositionX + player.Width >= bonus.posX and player.PositionX <= bonus.posX \
                        and bonus.posY + bonus.height >= player.PositionY) or \
                        (player.PositionX <= bonus.posX + bonus.width and player.PositionX >= bonus.posX and bonus.posY + bonus.height >= player.PositionY):

                    if bonus.bonusType == BONUS_COINS:
                        player.pointsSignal.emit(375)
                    elif bonus.bonusType == BONUS_NO_WEAPON:
                        player.weapon.isActive = False
                        player.bonusNoWeapon = True
                    bonus.bonus.hide()
                    self.bonuses.remove(bonus)

    def loadNextLevel(self):
        self.key_notifier.keys.clear()
        self.currentLevel += 1

        nextLevelType = random.choice([0, 1])

        for bonus in self.bonuses:
            bonus.bonus.hide()

        self.bonuses.clear()

        if nextLevelType == 0:
            if self.startingBallSize * 2 <= MAXBALLSIZE:
                self.startingBallSize = self.startingBallSize * 2
                self.balls.append(Ball(self, self.startingBallSize))
                self.balls[0].ball.setPixmap(self.balls[0].pixMapScaled)
                self.balls[0].ball.setGeometry(self.balls[0].x,
                                               self.balls[0].y,
                                               self.balls[0].size,
                                               self.balls[0].size)
                self.balls[0].ball.show()

                # self.currentAmp =  AMPLITUDE + 46
            else:
                nextLevelType = 1
        if nextLevelType == 1:
            self.previousBalls = self.previousBalls + 1
            temp = self.previousBalls
            for x in range(self.previousBalls):
                self.balls.append(Ball(self, self.startingBallSize))

            for b in self.balls:
                b.ball.setPixmap(b.pixMapScaled)
                if self.currentBall % 2 == 0:
                    b.x = b.x - 35 * temp
                    temp += 1
                    b.counter = b.x
                    b.ball.setGeometry(b.x, b.y, b.size, b.size)
                    b.forward = False
                elif self.currentBall % 2 == 1:
                    b.x = b.x + 35 * temp
                    temp += 1
                    b.counter = b.x
                    b.ball.setGeometry(b.x, b.y, b.size, b.size)
                b.ball.show()
                self.currentBall += 1

        self.stopOnStart = True

        for player in self.players:
            player.PositionX = player.initialPositionX
            player.update(Qt.Key_Minus)
            player.bonusNoWeapon = False
            if player.weapon.isActive:
                player.weapon.isActive = False
                player.weapon.update()

        self.getReadyLabel.setText('Get ready!')
        self.getReadyLabel.show()
        self.getReadyLabel.raise_()
        self.levelNumTag.setText(str(self.currentLevel))
        self.timer.start(20, self)

    def resetLevel(self):
        for ball in self.balls:
            ball.ball.hide()

        self.balls.clear()

        for bonus in self.bonuses:
            bonus.bonus.hide()

        self.bonuses.clear()

        for x in range(self.previousBalls):
            temp = x + 2
            self.balls.append(Ball(self, self.startingBallSize))
            self.balls[x].ball.setPixmap(self.balls[x].pixMapScaled)
            if x % 2 == 0:
                if len(self.balls) > 1:
                    self.balls[x].forward = False
                    self.balls[x].x = self.balls[x].x - 35 * temp
                self.balls[x].counter = self.balls[x].x
                self.balls[x].ball.setGeometry(self.balls[x].x,
                                               self.balls[x].y,
                                               self.balls[x].size,
                                               self.balls[x].size)
            elif x % 2 == 1:
                self.balls[x].x = self.balls[x].x + 35 * temp
                self.balls[x].counter = self.balls[x].x
                self.balls[x].ball.setGeometry(self.balls[x].x,
                                               self.balls[x].y,
                                               self.balls[x].size,
                                               self.balls[x].size)
            self.balls[x].ball.show()

        for player in self.players:
            player.PositionX = player.initialPositionX
            self.key_notifier.keys.clear()
            player.update(Qt.Key_Minus)
            player.bonusNoWeapon = False
            if player.weapon.isActive:
                player.weapon.isActive = False
                player.weapon.update()
        time.sleep(1)
        self.currentAmp = AMPLITUDE
        self.stopOnStart = True

        if not self.semiFinalEnd:
            self.getReadyLabel.setText('Get ready!')
        if not self.finishCup:
            self.timer.start(20, self)
        else:
            # gotov turnir, ispisi rezultate
            self.cupScores()

        self.getReadyLabel.show()
        self.getReadyLabel.raise_()

        self.semiFinalEnd = False

    def getPlayersFromSemifinal1(self, ind):
        points = self.deadPoints[ind].split('_')[0]
        playerName = self.deadPoints[ind].split('_')[1]
        semifinal1 = playerName + ' ' + points + '-' + self.deadPoints[ind+1].split('_')[0] + ' ' + \
                     self.deadPoints[ind+1].split('_')[1]
        return semifinal1

    def cupScores(self):

        # stringovi za ispis rezultata polufinala
        semifinal1 = self.getPlayersFromSemifinal1(0)
        semifinal2 = self.getPlayersFromSemifinal1(2)

        f1points = self.deadPoints[4].split('_')[
            0]  # finalist 1 points from final
        f1name = self.deadPoints[4].split('_')[1]  # finalist 1 name
        f2points = self.deadPoints[5].split('_')[
            0]  # finalist 2 points from final
        f2name = self.deadPoints[5].split('_')[1]  # finalist 2 name

        # string za ispis rezultata finala
        final = f1name + ' ' + f1points + '-' + f2points + ' ' + f2name

        # ime pobjednika je u winner-u
        winner = ''

        if int(f1points) > int(f2points):
            winner = f1name
        elif int(f1points) == int(
                f2points
        ):  # ako imaju isti broj poena u finalu neka pobijedi onaj koji je imao
            # vise u polufinalu, a ako opet imaju isto neka pobijedi domacin
            if int(self.finalist1points) > int(
                    self.finalist2points
            ):  # prvi finalista je imao vise u polufinalu

                winner = self.finalist1.upper()

            elif int(self.finalist1points) < int(
                    self.finalist2points
            ):  # drugi finalista je imao vise u polufinalu

                winner = self.finalist2.upper()

            else:  # imali su isto poena i u polufinalu
                if int(f1name[-1]) < int(f2name[-1]):
                    winner = f1name
                else:
                    winner = f2name
        else:
            winner = f2name

        self.getReadyLabel.setText('SF 1: ' + semifinal1 + '\nSF 2: ' +
                                   semifinal2 + '\nFINAL: ' + final +
                                   '\nWINNER: ' + winner)

    def updateLives(self):
        sender = self.sender()

        livesPic = None
        lives = sender.lifes

        if sender.playerId == 'player1':
            livesPic = self.livesPic1
        elif sender.playerId == 'player2':
            livesPic = self.livesPic2

        queueCalcLives.put(str(lives))
        res = str(queueResLives.get())

        sender.lifes = int(res)

        self.updatePlayerPixMapLives(livesPic, sender.lifes, sender)

        if sender.lifes == 0:
            sender.isDead = True

        if sender.isDead:
            if sender.playerId == 'player1':
                self.deadPoints.append(self.player1PointsTag.text() + '_' +
                                       self.player1Tag.text())
            elif sender.playerId == 'player2':
                self.deadPoints.append(self.player2PointsTag.text() + '_' +
                                       self.player2Tag.text())
            sender.player.hide()
            self.players.remove(sender)

        if len(self.players) == 0:
            if self.finalGame:
                self.finishCup = True

            p1points = int(self.player1PointsTag.text())
            p2points = int(self.player2PointsTag.text())
            if len(self.cupPlayers) == 0:
                if p1points >= p2points:
                    self.cupPlayers.append('player 1,' + str(p1points))
                else:
                    self.cupPlayers.append('player 2,' + str(p2points))
            else:
                if p1points >= p2points:
                    self.cupPlayers.append('player 3,' + str(p1points))
                else:
                    self.cupPlayers.append('player 4,' + str(p2points))
            self.gameOver()

    def updatePoints(self, num):
        sender = self.sender()

        playerLabel = None
        previous = None

        if sender.playerId == 'player1':
            previous = self.player1PointsTag.text()
            playerLabel = self.player1PointsTag
        elif sender.playerId == 'player2':
            previous = self.player2PointsTag.text()
            playerLabel = self.player2PointsTag

        queueForCalcs.put(sender.playerId + ',' + str(previous) + ',' +
                          str(num))
        points = str(queueForResults.get())

        playerLabel.setText(points)

    def gameOver(self):
        if not self.cupMode:
            self.getReadyLabel.setText("Game over")
            self.getReadyLabel.show()
            self.getReadyLabel.raise_()

        self.timer.stop()

        if self.cupMode:
            self.playerWon = self.cupPlayers[len(self.cupPlayers) - 1]
            self.getReadyLabel.setText(
                self.playerWon.split(',')[0].upper() + " WON!")
            self.cupModeLogic()

    def cupModeLogic(self):
        self.players = [Player(self, 'player1', 2), Player(self, 'player2', 2)]

        self.initStartingLevel()
        self.initCupPlayers()

        self.resetPlayerPixMapLives(self.players[0].lifes)

        if len(self.cupPlayers) == 1:  # pocelo drugo polufinale
            self.getReadyLabel.setText(
                self.playerWon.split(',')[0].upper() + " WON!")

            self.player1Tag.setText('PLAYER 3')
            self.player2Tag.setText('PLAYER 4')
        else:  # pocelo finale
            self.finalist1 = self.cupPlayers[0].split(',')[0]
            self.finalist1points = self.cupPlayers[0].split(',')[1]
            self.finalist2 = self.cupPlayers[1].split(',')[0]

            self.finalist2points = self.cupPlayers[1].split(',')[1]

            self.player1Tag.setText(self.finalist1.upper())
            self.player2Tag.setText(self.finalist2.upper())

            self.finalGame = True
        self.resetLevel()

    def initStartingLevel(
            self):  # vrati poene na 0, loptu na inicijalnu, level na 1
        self.player1PointsTag.setText('0')
        self.player2PointsTag.setText('0')
        self.semiFinalEnd = True
        self.currentLevel = 1
        self.levelNumTag.setText(str(self.currentLevel))
        self.previousBalls = 1
        self.currentAmp = AMPLITUDE
        self.startingBallSize = MINBALLSIZE * 2 + 1
        self.semiFinalEnd = True

    def initCupPlayers(self):
        self.players[0].weapon.weapon = self.weaponObj.weapon
        self.players[1].weapon.weapon = self.weaponObj2.weapon

        for p in self.players:
            p.player.setPixmap(p.PixMap)
            p.weapon.weapon.show()
            p.livesSignal.connect(self.updateLives)
            p.pointsSignal.connect(self.updatePoints)

            p.player.show()