示例#1
0
    def __init__(self, previewImage, fileName):
        super(ImageView, self).__init__()

        self.fileName = fileName

        mainLayout = QVBoxLayout(self)
        self.imageLabel = QLabel()
        self.imageLabel.setPixmap(QPixmap.fromImage(previewImage))
        mainLayout.addWidget(self.imageLabel)

        topLayout = QHBoxLayout()
        self.fileNameLabel = QLabel(QDir.toNativeSeparators(fileName))
        self.fileNameLabel.setTextInteractionFlags(Qt.TextBrowserInteraction)

        topLayout.addWidget(self.fileNameLabel)
        topLayout.addStretch()
        copyButton = QPushButton("Copy")
        copyButton.setToolTip("Copy file name to clipboard")
        topLayout.addWidget(copyButton)
        copyButton.clicked.connect(self.copy)
        launchButton = QPushButton("Launch")
        launchButton.setToolTip("Launch image viewer")
        topLayout.addWidget(launchButton)
        launchButton.clicked.connect(self.launch)
        mainLayout.addLayout(topLayout)
示例#2
0
    def __init__(self, parent=None):
        super(AddDialogWidget, self).__init__(parent)

        nameLabel = QLabel("Name")
        addressLabel = QLabel("Address")
        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok |
                                      QDialogButtonBox.Cancel)

        self.nameText = QLineEdit()
        self.addressText = QTextEdit()

        grid = QGridLayout()
        grid.setColumnStretch(1, 2)
        grid.addWidget(nameLabel, 0, 0)
        grid.addWidget(self.nameText, 0, 1)
        grid.addWidget(addressLabel, 1, 0, Qt.AlignLeft | Qt.AlignTop)
        grid.addWidget(self.addressText, 1, 1, Qt.AlignLeft)

        layout = QVBoxLayout()
        layout.addLayout(grid)
        layout.addWidget(buttonBox)

        self.setLayout(layout)

        self.setWindowTitle("Add a Contact")

        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)
示例#3
0
    def __init__(self, argv, parentQWidget = None):
        QWidget.__init__(self)

        const.mode_interactive = 1
        const.mode_file = 2
        const.mode_batch = 3
        const.mode_default = const.mode_batch

        arg_file = ''
        if '-i' in argv:
            mode = const.mode_interactive
        elif '-b' in argv:
            mode = const.mode_batch
        elif '-f' in argv:
            mode = const.mode_file
            idx = argv.index('-f')
            arg_file = argv[idx+1]

        src_path = None
        if '-s' in argv:
            idx = argv.index('-s')
            src_path = argv[idx+1]

        if '-c' in argv:
            idx = argv.index('-c')
            cfg_file = argv[idx+1]

        hbox = QHBoxLayout()
        vbox = QVBoxLayout()
        scrollView = ScrollArea()
        headerView = Header.Header(self)
        scrollView.connectHeaderView(headerView)
        headerView.connectMainView(scrollView.mainView.drawer)
        vbox.addWidget(headerView)
        vbox.addWidget(scrollView)

        toolBox = ToolBox.ToolBox(mode)

        hbox.addLayout(vbox)
        hbox.addLayout(toolBox)

        self.controller = Kitchen.Kitchen(mode,arg_file,cfg_file)
        self.controller.connectView(scrollView.mainView.drawer)
        self.controller.connectToolBox(toolBox)
        self.controller.start()

        srcViewer = SourceViewer.SourceViewer()
        srcViewer.createIndex(src_path)

        toolBox.connectMsgRcv(headerView)
        toolBox.connectMsgRcv(scrollView.mainView.drawer)
        toolBox.connectMsgRcv(self.controller)
        toolBox.connectDiagramView(scrollView.mainView.drawer)

        scrollView.mainView.drawer.setToolBox(toolBox)
        scrollView.mainView.drawer.connectSourceViewer(srcViewer)

        self.setLayout(hbox)
示例#4
0
	def __init__(self, parent = None):
		super(Form, self).__init__(parent)

		self.setWindowTitle('My Form')

		self.edit = QLineEdit('Write your name here...')
		self.button = QPushButton('Show Greetings')

		layout = QVBoxLayout()
		layout.addWidget(self.edit)
		layout.addWidget(self.button)
		self.setLayout(layout)

		self.button.clicked.connect(self.greetings)
示例#5
0
    def __init__(self, parent=None):
        super(NewAddressTab, self).__init__(parent)

        descriptionLabel = QLabel("There are no contacts in your address book."
                                   "\nClick Add to add new contacts.")

        addButton = QPushButton("Add")

        layout = QVBoxLayout()
        layout.addWidget(descriptionLabel)
        layout.addWidget(addButton, 0, Qt.AlignCenter)

        self.setLayout(layout)

        addButton.clicked.connect(self.addEntry)
    def __init__(self, hiddenLifeline, parent = None):
        super(ShowLifeLineDialog, self).__init__(parent)

        self.theHidden = hiddenLifeline
        layout = QVBoxLayout(self)

        listTitle = QLabel("The message you want to see is blocked by a hidden class object.\n\n%s\n\nDo you want to show the hidden class object?" % hiddenLifeline)
        layout.addWidget(listTitle)

        buttons = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
        buttons.button(QDialogButtonBox.Ok).setText('Yes')
        buttons.button(QDialogButtonBox.Cancel).setText('No')
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)
示例#7
0
文件: ui.py 项目: vojtamolda/games
    def initUI(self):
        self.setWindowTitle(self.tr("Tic-Tac-Toe"))
        layout = QVBoxLayout()
        self.setLayout(layout)
        gridLayout = QGridLayout()
        gridLayout.setSpacing(3)
        aiComboBox = QComboBox(self)
        aiComboBox.addItems([self.tr(ai) for ai in self.AIs])
        aiComboBox.currentTextChanged.connect(self.selectAI)
        layout.addWidget(aiComboBox)
        layout.addLayout(gridLayout)

        for tile in self.ticTacToe:
            button = QTicTacToe.QTileButton(self, tile)
            gridLayout.addWidget(button, tile.row, tile.column)
            button.clicked.connect(button.clickEvent)
            tile.delegate = button
    def __init__(self, parent=None):
        super(AddressWidget, self).__init__(parent)

        self.tableModel = TableModel()
        self.tableView = QTableView()
        self.setupTable()

        statusLabel = QLabel("Tabular data view demo")

        layout = QVBoxLayout()
        layout.addWidget(self.tableView)
        layout.addWidget(statusLabel)
        self.setLayout(layout)
        self.setWindowTitle("Address Book")
        self.resize(800,500)

        # add test data
        self.populateTestData()
示例#9
0
文件: ui.py 项目: vojtamolda/games
    def initUI(self):
        self.setWindowTitle(self.tr("Fourplay"))
        layout = QVBoxLayout()
        self.setLayout(layout)
        discGridLayout = QGridLayout()
        discGridLayout.setSpacing(4)
        aiComboBox = QComboBox(self)
        aiComboBox.addItems([self.tr(ai) for ai in self.AIs])
        aiComboBox.currentTextChanged.connect(lambda: self.selectAI())
        layout.addWidget(aiComboBox)
        layout.addLayout(discGridLayout)

        for disc in self.fourPlay:
            qDisc = QFourPlay.QDiscButton(self)
            discGridLayout.addWidget(qDisc, disc.row, disc.column)
            qDisc.clicked.connect(lambda qDisc=qDisc, disc=disc: qDisc.clickEvent(disc))
            qDisc.marked(disc)
            disc.delegate = qDisc
示例#10
0
class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
 
        self.hello = ["Hallo welt!", "Ciao mondo!",
            "Hei maailma!", "Hola mundo!", "Hei verden!"]
 
        self.button = QPushButton("Click me!")
        self.text = QLabel("Hello World")
        self.text.setAlignment(Qt.AlignCenter)
 
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.text)
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)
 
        self.button.clicked.connect(self.magic)
 
    def magic(self):
        self.text.setText(random.choice(self.hello))
    def test_setLayout(self):
        layout = QVBoxLayout()
        btn1 = QPushButton("button_v1")
        layout.addWidget(btn1)

        btn2 = QPushButton("button_v2")
        layout.addWidget(btn2)

        layout2 = QHBoxLayout()

        btn1 = QPushButton("button_h1")
        layout2.addWidget(btn1)

        btn2 = QPushButton("button_h2")
        layout2.addWidget(btn2)

        layout.addLayout(layout2)

        widget = QWidget()
        widget.setLayout(layout)
    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        self.server = FortuneServer()

        statusLabel = QLabel()
        statusLabel.setTextInteractionFlags(Qt.TextBrowserInteraction)
        statusLabel.setWordWrap(True)
        quitButton = QPushButton("Quit")
        quitButton.setAutoDefault(False)

        if not self.server.listen():
            QMessageBox.critical(self, "Threaded Fortune Server",
                    "Unable to start the server: %s." % self.server.errorString())
            self.close()
            return

        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        ipAddress = ipAddress.toString()

        statusLabel.setText("The server is running on\n\nIP: %s\nport: %d\n\n"
                "Run the Fortune Client example now." % (ipAddress, self.server.serverPort()))

        quitButton.clicked.connect(self.close)

        buttonLayout = QHBoxLayout()
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(quitButton)
        buttonLayout.addStretch(1)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(statusLabel)
        mainLayout.addLayout(buttonLayout)
        self.setLayout(mainLayout)

        self.setWindowTitle("Threaded Fortune Server")
示例#13
0
文件: help.py 项目: strohne/Facepager
    def __init__(self, parent=None):
        super(HelpWindow,self).__init__(parent)

        self.setWindowTitle("Facepager 3.0 - Help")
        self.setMinimumWidth(600);
        self.setMinimumHeight(600);
        central = QWidget()
        self.setCentralWidget(central)
        vLayout = QVBoxLayout(central)

        self.page = MyQWebEnginePage()
        self.browser = QWebEngineView(central)
        self.browser.setPage(self.page)

        vLayout.addWidget(self.browser)
        hLayout = QHBoxLayout()
        vLayout.addLayout(hLayout)
        hLayout.addStretch(5)
        dismiss = QPushButton(central)
        dismiss.setText("Close")
        dismiss.clicked.connect(self.hide)
        hLayout.addWidget(dismiss)
示例#14
0
    def __init__(self, lifeline, defaultName, parent = None):
        super(ClusterDialog, self).__init__(parent)

        self.lifeline = lifeline
        layout = QVBoxLayout(self)

        message = QLabel('Enter group name')
        layout.addWidget(message)

        self.editClusterName = QLineEdit(defaultName)
        self.editClusterName.setFixedHeight(30)
        self.editClusterName.setFixedWidth(400)
        self.editClusterName.textChanged.connect(self.validateCluster)
        layout.addWidget(self.editClusterName)

        self.validation_msg = QLabel(' ')
        layout.addWidget(self.validation_msg)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

        self.validateCluster()
示例#15
0
    def __init__(self, messages, hiddenLifelines, parent = None):
        super(HiddenMessageDialog, self).__init__(parent)

        self.lifelineList = hiddenLifelines
        self.msgList = messages
        layout = QVBoxLayout(self)

        listTitle = QLabel('Hidden Messages')
        layout.addWidget(listTitle)

        self.listHiddenMessages = QTableWidget(len(self.msgList),4)
        self.listHiddenMessages.setHorizontalHeaderLabels(['Index','Name','Departure','Destination'])
        self.listHiddenMessages.setFixedWidth(400)
        #self.listHiddenMessages.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)
        self.listHiddenMessages.setSelectionBehavior(QAbstractItemView.SelectRows)

        for idx, msg in enumerate(self.msgList):
            self.listHiddenMessages.setItem(idx,0,QTableWidgetItem("%d" % msg['messageindex']))
            self.listHiddenMessages.setItem(idx,1,QTableWidgetItem(msg['message']))
            item = QTableWidgetItem(msg['departure']['class'])
            item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
            if msg['departure']['class'] in self.lifelineList:
                item.setForeground(QColor(200,200,200)) 
            self.listHiddenMessages.setItem(idx,2,item)

            item = QTableWidgetItem(msg['dest'])
            item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
            if msg['dest'] in self.lifelineList:
                item.setForeground(QColor(200,200,200)) 
            self.listHiddenMessages.setItem(idx,3,item)

        layout.addWidget(self.listHiddenMessages)

        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
        buttons.button(QDialogButtonBox.Ok).setText('Show')
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)
示例#16
0
    def initializeWindow(self):
        layout = QVBoxLayout()

        self.m_deviceBox = QComboBox()
        self.m_deviceBox.activated[int].connect(self.deviceChanged)
        for deviceInfo in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput):
            self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo)

        layout.addWidget(self.m_deviceBox)

        self.m_modeButton = QPushButton()
        self.m_modeButton.clicked.connect(self.toggleMode)
        self.m_modeButton.setText(self.PUSH_MODE_LABEL)

        layout.addWidget(self.m_modeButton)

        self.m_suspendResumeButton = QPushButton(
                clicked=self.toggleSuspendResume)
        self.m_suspendResumeButton.setText(self.SUSPEND_LABEL)

        layout.addWidget(self.m_suspendResumeButton)

        volumeBox = QHBoxLayout()
        volumeLabel = QLabel("Volume:")
        self.m_volumeSlider = QSlider(Qt.Horizontal, minimum=0, maximum=100,
                singleStep=10)
        self.m_volumeSlider.valueChanged.connect(self.volumeChanged)

        volumeBox.addWidget(volumeLabel)
        volumeBox.addWidget(self.m_volumeSlider)

        layout.addLayout(volumeBox)

        window = QWidget()
        window.setLayout(layout)

        self.setCentralWidget(window)
示例#17
0
class ControlWidget(QWidget):
    def __init__(self, parent=None):
        super(ControlWidget, self).__init__(parent)
        self.set_init_settings()
        self.setup_ui()
        self.setup_labeling_func()
        self.setup_file_func()
        self.set_check()
        self.set_check_func()
        self.set_size()
        self.setFocusPolicy(QtCore.Qt.StrongFocus)

    def set_size(self):
        self.l_layout.setAlignment(QtCore.Qt.AlignTop)

        self.select_button.setSizePolicy(QSizePolicy.Minimum,
                                         QSizePolicy.Minimum)
        self.save_button.setSizePolicy(QSizePolicy.Minimum,
                                       QSizePolicy.Minimum)
        self.delete_button.setSizePolicy(QSizePolicy.Minimum,
                                         QSizePolicy.Minimum)
        self.image_w.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.label_w.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.filelist_w.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Minimum)

        self.f_widget.setFixedHeight(40)
        self.f_2widget.setFixedHeight(40)
        self.file_name.setFixedHeight(40)

        self.l_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.r_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

    def set_init_settings(self):
        self.auto_load_next_data = False
        self.auto_save = True

    def setup_ui(self):
        """Initialize widgets.
        """
        self.file_name = QLabel()
        self.f_widget = self.setup_func_widget()
        self.f_2widget = self.setup_second_func_widget()
        self.label_w = LabelWidget(self)
        self.image_w = ImageWidget(self.label_w, self)
        self.filelist_w = FilelistWidget(self)

        self.l_layout = QVBoxLayout()
        self.l_layout.addWidget(self.file_name)
        self.l_layout.addWidget(self.image_w)
        self.l_layout.addWidget(self.f_widget)
        self.l_layout.addWidget(self.f_2widget)
        self.l_widget = QWidget()
        self.l_widget.setLayout(self.l_layout)

        self.r_layout = QVBoxLayout()
        self.r_layout.addWidget(self.label_w)
        self.r_layout.addWidget(self.filelist_w)
        self.r_widget = QWidget()
        self.r_widget.setLayout(self.r_layout)

        self.h_layout = QHBoxLayout()
        self.h_layout.addWidget(self.l_widget)
        self.h_layout.addWidget(self.r_widget)

        self.setLayout(self.h_layout)

    def setup_func_widget(self):
        f_widget = QWidget()
        f_layout = QHBoxLayout()
        self.select_button = QPushButton("Open Dir")
        self.select_button.clicked.connect(self.select_dir)
        self.save_button = QPushButton("Save")
        self.save_button.clicked.connect(self.save_data)
        self.delete_button = QPushButton("Delete")
        self.delete_button.clicked.connect(self.delete_data)
        self.auto_load_next_data_box = QCheckBox("Auto Load Next")
        self.auto_save_box = QCheckBox("Auto Save")
        self.auto_take_over_last_data_box = QCheckBox("Auto Use Last label")

        f_layout.addWidget(self.select_button)
        f_layout.addWidget(self.save_button)
        f_layout.addWidget(self.delete_button)
        f_layout.addWidget(self.auto_load_next_data_box)
        f_layout.addWidget(self.auto_save_box)
        f_layout.addWidget(self.auto_take_over_last_data_box)
        f_widget.setLayout(f_layout)
        return f_widget

    def setup_second_func_widget(self):
        f_widget = QWidget()
        f_layout = QHBoxLayout()
        self.left_button = QPushButton("←")
        self.left_button.clicked.connect(
            lambda: self.open_data(self.filelist_w.select_filepath_back()))
        self.right_button = QPushButton("→")
        self.right_button.clicked.connect(
            lambda: self.open_data(self.filelist_w.select_filepath()))

        f_layout.addWidget(self.left_button)
        f_layout.addWidget(self.right_button)
        f_widget.setLayout(f_layout)
        return f_widget

    def set_check(self):
        self.auto_load_next_data_box.setChecked(self.auto_load_next_data)
        self.auto_save_box.setChecked(self.auto_save)
        self.auto_take_over_last_data_box.setChecked(
            self.image_w.auto_take_over_last_data)

    def set_check_func(self):
        self.auto_load_next_data_box.stateChanged.connect(self.change_check)
        self.auto_save_box.stateChanged.connect(self.change_check)
        self.auto_take_over_last_data_box.stateChanged.connect(
            self.change_check)

    def change_check(self):
        self.auto_load_next_data = self.auto_load_next_data_box.isChecked()
        self.auto_save = self.auto_save_box.isChecked()
        self.image_w.auto_take_over_last_data = self.auto_take_over_last_data_box.isChecked(
        )

    def setup_labeling_func(self):
        for w in self.label_w.level_buttons:
            w.clicked.connect(self.labeling)

    def setup_file_func(self):
        for w in self.filelist_w.filelabel_list:
            w.clicked.connect(self.clicked_file)

    def labeling(self):
        lbutton = self.sender()
        return self.__f_labeling(int(lbutton.text()) - 1)

    def __f_labeling(self, level):
        self.image_w.update_labeling_data(level)
        if self.auto_load_next_data:
            if self.image_w.is_last_idx():
                self.save_data()
                self.open_data(self.filelist_w.select_filepath())
                return
        # self.image_w.update_selected_idx()
        img, level = self.image_w.get_selected_area_image()
        self.label_w.update_limage(img, level)

    def save_data(self):
        self.image_w.save_labeling_data(self.auto_save)

    def delete_data(self):
        self.image_w.delete_labeling_data()

    def select_dir(self):
        self.filelist_w.select_dir()
        self.setup_file_func()
        self.open_data(self.filelist_w.get_selected_path())

    def open_data(self, file_path):
        if file_path:
            self.save_data()
            self.file_name.setText(file_path)
            self.image_w.load_image(file_path, self.filelist_w.selected_idx)
            img, level = self.image_w.get_selected_area_image()
            self.label_w.update_limage(img, level)

    def clicked_file(self):
        filelabel = self.sender()
        id = filelabel.id
        self.save_data()
        self.open_data(self.filelist_w.select_filepath(id))

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

    def keyPressEvent(self, event):
        if event.modifiers() == QtCore.Qt.ControlModifier:
            if event.key() == QtCore.Qt.Key_Up:
                self.image_w.move_selected_idx(v=-1, h=0)
            if event.key() == QtCore.Qt.Key_Down:
                self.image_w.move_selected_idx(v=1, h=0)
            if event.key() == QtCore.Qt.Key_Left:
                self.image_w.move_selected_idx(v=0, h=-1)
            if event.key() == QtCore.Qt.Key_Right:
                self.image_w.move_selected_idx(v=0, h=1)
        else:
            if event.key() == QtCore.Qt.Key_Up:
                self.open_data(self.filelist_w.select_filepath_back())
            if event.key() == QtCore.Qt.Key_Down:
                self.open_data(self.filelist_w.select_filepath())
            if event.key() == QtCore.Qt.Key_Left:
                self.open_data(self.filelist_w.select_filepath_back())
            if event.key() == QtCore.Qt.Key_Right:
                self.open_data(self.filelist_w.select_filepath())
            if event.key() == QtCore.Qt.Key_1:
                self.__f_labeling(0)
            if event.key() == QtCore.Qt.Key_2:
                self.__f_labeling(1)
            if event.key() == QtCore.Qt.Key_3:
                self.__f_labeling(2)
示例#18
0
        class MyWidget(QWidget):
            def __init__(self, parent):
                super().__init__(parent)
                self.buttons_id_value = {
                    1: ('comma', ','),
                    2: ('space', '\b'),
                    3: ('tab', '\t'),
                    4: ('semicolon', ';')
                }
                self.separator = QButtonGroup()
                lab = QLabel()
                lab.setText('Choose a separator:')
                for bid, value in self.buttons_id_value.items():
                    self.separator.addButton(QRadioButton(value[0]), id=bid)
                self.separator.setExclusive(True)
                self.default_button = self.separator.button(1)
                button_layout = QHBoxLayout()
                for button in self.separator.buttons():
                    button_layout.addWidget(button)
                self.default_button.click()

                openFileChooser = QPushButton('Choose')
                fileChooser = QFileDialog(self, 'Open csv', str(os.getcwd()),
                                          'Csv (*.csv *.tsv *.dat)')
                fileChooser.setFileMode(QFileDialog.ExistingFile)
                self.filePath = QLineEdit()
                openFileChooser.released.connect(fileChooser.show)
                fileChooser.fileSelected.connect(self.filePath.setText)
                self.filePath.textChanged.connect(self.checkFileExists)
                nameLabel = QLabel('Select a name:', self)
                self.nameField = QLineEdit(self)
                self.nameErrorLabel = QLabel(self)

                self.file_layout = QVBoxLayout()
                fileChooserLayout = QHBoxLayout()
                nameRowLayout = QHBoxLayout()
                fileChooserLayout.addWidget(openFileChooser)
                fileChooserLayout.addWidget(self.filePath)
                nameRowLayout.addWidget(nameLabel)
                nameRowLayout.addWidget(self.nameField)
                self.fileErrorLabel = QLabel(self)
                self.file_layout.addLayout(fileChooserLayout)
                self.file_layout.addWidget(self.fileErrorLabel)
                self.file_layout.addLayout(nameRowLayout)
                self.file_layout.addWidget(self.nameErrorLabel)
                self.fileErrorLabel.hide()
                self.nameErrorLabel.hide()
                self.tablePreview = SearchableAttributeTableWidget(self, True)
                self.tableSpinner = QtWaitingSpinner(
                    self.tablePreview,
                    centerOnParent=True,
                    disableParentWhenSpinning=True)
                self.nameField.textEdited.connect(self.nameErrorLabel.hide)

                # Split file by row
                splitRowLayout = QHBoxLayout()
                self.checkSplit = QCheckBox('Split file by rows', self)
                self.numberRowsChunk = QLineEdit(self)
                self.numberRowsChunk.setPlaceholderText(
                    'Number of rows per chunk')
                self.numberRowsChunk.setValidator(QIntValidator(self))
                splitRowLayout.addWidget(self.checkSplit)
                splitRowLayout.addWidget(self.numberRowsChunk)
                self.checkSplit.stateChanged.connect(self.toggleSplitRows)

                layout = QVBoxLayout()
                layout.addLayout(self.file_layout)
                layout.addWidget(lab)
                layout.addLayout(button_layout)
                layout.addLayout(splitRowLayout)
                layout.addWidget(QLabel('Preview'))
                layout.addWidget(self.tablePreview)
                self.setLayout(layout)

                self.filePath.textChanged.connect(self.loadPreview)
                self.separator.buttonClicked.connect(self.loadPreview)

            @Slot(object)
            def loadPreview(self) -> None:
                if not os.path.isfile(self.filePath.text()):
                    return

                class WorkerThread(QThread):
                    resultReady = Signal(Frame)

                    def __init__(self, path: str, separ: str, parent=None):
                        super().__init__(parent)
                        self.__path = path
                        self.__sep = separ

                    def run(self):
                        header = pd.read_csv(self.__path,
                                             sep=self.__sep,
                                             index_col=False,
                                             nrows=0)
                        self.resultReady.emit(Frame(header))

                sep: int = self.separator.checkedId()
                sep_s: str = self.buttons_id_value[sep][
                    1] if sep != -1 else None
                assert sep_s is not None

                # Async call to load header
                worker = WorkerThread(path=self.filePath.text(),
                                      separ=sep_s,
                                      parent=self)
                worker.resultReady.connect(self.onPreviewComputed)
                worker.finished.connect(worker.deleteLater)
                self.tableSpinner.start()
                worker.start()

            @Slot(Frame)
            def onPreviewComputed(self, header: Frame):
                self.tablePreview.setSourceFrameModel(FrameModel(self, header))
                self.tablePreview.model().setAllChecked(True)
                self.tableSpinner.stop()

            @Slot(str)
            def checkFileExists(self, path: str) -> None:
                file_exists = os.path.isfile(path)
                if not file_exists:
                    self.fileErrorLabel.setText('File does not exists!')
                    self.fileErrorLabel.setStyleSheet('color: red')
                    self.filePath.setToolTip('File does not exists!')
                    self.filePath.setStyleSheet('border: 1px solid red')
                    # self.file_layout.addWidget(self.fileErrorLabel)
                    self.parentWidget().disableOkButton()
                    self.fileErrorLabel.show()
                else:
                    # self.file_layout.removeWidget(self.fileErrorLabel)
                    self.fileErrorLabel.hide()
                    self.filePath.setStyleSheet('')
                    self.parentWidget().enableOkButton()
                    if not self.nameField.text():
                        name: str = os.path.splitext(os.path.basename(path))[0]
                        self.nameField.setText(name)

            @Slot(Qt.CheckState)
            def toggleSplitRows(self, state: Qt.CheckState) -> None:
                if state == Qt.Checked:
                    self.numberRowsChunk.setEnabled(True)
                else:
                    self.numberRowsChunk.setDisabled(True)

            def showNameError(self, msg: str) -> None:
                self.nameErrorLabel.setText(msg)
                self.nameErrorLabel.setStyleSheet('color: red')
                self.nameErrorLabel.show()
示例#19
0
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle("Spot Extractor")

        menuBar = self.buildMenuBar()
        widget = QWidget(self)
        layout = QGridLayout(widget)

        # Main Image Window
        self.scrollArea = QScrollArea()
        self.imageLabel = ImageLabel(self)
        self.scrollArea.setWidget(self.imageLabel)

        # Text Label for Lot Name
        self.lotNameTextField = QLineEdit()
        self.lotNameTextField.setFixedWidth(300)

        # Spot List
        self.spotList = SpotListWidget(self)

        # Image Box Layout
        imageGroupBox = QGroupBox("Image")
        imageLayout = QHBoxLayout()
        imageLayout.addWidget(self.scrollArea)
        imageGroupBox.setLayout(imageLayout)

        # Spot List Box Layout
        rightGroupBox = QGroupBox()
        rightGroupBox.setMaximumWidth(300)
        rightGroupLayout = QVBoxLayout()

        lotNameGroupBox = QGroupBox("Lot Name")
        lotNameLayout = QHBoxLayout()
        lotNameLayout.addWidget(self.lotNameTextField)
        lotNameGroupBox.setLayout(lotNameLayout)

        spotsGroupBox = QGroupBox("Spot List")
        spotsLayout = QHBoxLayout()
        spotsLayout.addWidget(self.spotList)
        spotsGroupBox.setLayout(spotsLayout)

        rightGroupLayout.addWidget(lotNameGroupBox)
        rightGroupLayout.addWidget(spotsGroupBox)
        rightGroupBox.setLayout(rightGroupLayout)

        # Control Buttons Box Layout
        horizontalGroupBox = QGroupBox("Control Buttons")
        controlButtonLayout = QHBoxLayout()
        checkAllButton = QPushButton("Check All")
        uncheckAllButton = QPushButton("Uncheck All")
        deleteCheckedButton = QPushButton("Delete Checked")
        checkAllButton.clicked.connect(self.checkAll)
        uncheckAllButton.clicked.connect(self.uncheckAll)
        deleteCheckedButton.clicked.connect(self.deleteAllChecked)
        controlButtonLayout.addWidget(checkAllButton)
        controlButtonLayout.addWidget(uncheckAllButton)
        controlButtonLayout.addWidget(deleteCheckedButton)
        horizontalGroupBox.setLayout(controlButtonLayout)

        layout.addWidget(imageGroupBox, 0, 0)
        layout.addWidget(rightGroupBox, 0, 1)
        layout.addWidget(horizontalGroupBox, 1, 0, 1, 2)

        self.setMenuBar(menuBar)
        self.setLayout(layout)
        self.setCentralWidget(widget)
示例#20
0
    def __init__(self, image, parent=None):
        super(ToolWidget, self).__init__(parent)

        self.rgb_radio = QRadioButton(self.tr('RGB'))
        self.rgb_radio.setChecked(True)
        self.last_radio = self.rgb_radio
        self.red_radio = QRadioButton(self.tr('Red'))
        self.green_radio = QRadioButton(self.tr('Green'))
        self.blue_radio = QRadioButton(self.tr('Blue'))
        self.value_radio = QRadioButton(self.tr('Value'))
        self.log_check = QCheckBox(self.tr('Log scale'))
        self.grid_check = QCheckBox(self.tr('Show grid'))
        self.marker_check = QCheckBox(self.tr('Show markers'))
        self.marker_check.setToolTip(
            self.tr('Show plot markers for min(--), avg(-), max(-.)'))
        self.start_slider = ParamSlider([0, 255],
                                        8,
                                        0,
                                        label='Start:',
                                        bold=True)
        self.end_slider = ParamSlider([0, 255],
                                      8,
                                      255,
                                      label='End:',
                                      bold=True)

        channels = cv.split(cv.cvtColor(image, cv.COLOR_BGR2RGB))
        channels.append(cv.cvtColor(image, cv.COLOR_BGR2GRAY))
        self.hist = [compute_hist(c) for c in channels]
        rows, cols, chans = image.shape
        pixels = rows * cols
        unique = np.unique(np.reshape(image, (pixels, chans)), axis=0).shape[0]
        unique_ratio = unique / pixels * 100
        unique_label = QLabel(
            self.tr('total pixels = {}, unique colors = {} ({:.2f}%) '.format(
                pixels, unique, unique_ratio)))
        modify_font(unique_label, italic=True)

        self.rgb_radio.clicked.connect(self.redraw)
        self.red_radio.clicked.connect(self.redraw)
        self.green_radio.clicked.connect(self.redraw)
        self.blue_radio.clicked.connect(self.redraw)
        self.value_radio.clicked.connect(self.redraw)
        self.log_check.stateChanged.connect(self.redraw)
        self.grid_check.stateChanged.connect(self.redraw)
        self.marker_check.stateChanged.connect(self.redraw)
        self.start_slider.valueChanged.connect(self.redraw)
        self.end_slider.valueChanged.connect(self.redraw)

        self.table_widget = QTableWidget(8, 2)
        self.table_widget.setHorizontalHeaderLabels(
            [self.tr('Property'), self.tr('Value')])
        self.table_widget.setItem(0, 0,
                                  QTableWidgetItem(self.tr('Least frequent')))
        self.table_widget.setItem(1, 0,
                                  QTableWidgetItem(self.tr('Most frequent')))
        self.table_widget.setItem(2, 0,
                                  QTableWidgetItem(self.tr('Average level')))
        self.table_widget.setItem(3, 0,
                                  QTableWidgetItem(self.tr('Median level')))
        self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('Deviation')))
        self.table_widget.setItem(5, 0,
                                  QTableWidgetItem(self.tr('Pixel count')))
        self.table_widget.setItem(6, 0,
                                  QTableWidgetItem(self.tr('Percentile')))
        self.table_widget.setItem(7, 0,
                                  QTableWidgetItem(self.tr('Smoothness')))
        for i in range(self.table_widget.rowCount()):
            modify_font(self.table_widget.item(i, 0), bold=True)
        self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_widget.resizeColumnsToContents()
        self.table_widget.setAlternatingRowColors(True)
        self.table_widget.setMaximumWidth(200)

        figure = Figure()
        plot_canvas = FigureCanvas(figure)
        # plot_canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        self.axes = plot_canvas.figure.subplots()
        self.redraw()
        figure.set_tight_layout(True)

        right_layout = QVBoxLayout()
        table_label = QLabel(self.tr('Range properties'))
        modify_font(table_label, bold=True)
        table_label.setAlignment(Qt.AlignCenter)
        right_layout.addWidget(table_label)
        right_layout.addWidget(self.table_widget)
        right_layout.addWidget(self.marker_check)
        right_layout.addWidget(self.start_slider)
        right_layout.addWidget(self.end_slider)

        center_layout = QHBoxLayout()
        center_layout.addWidget(plot_canvas)
        center_layout.addLayout(right_layout)

        bottom_layout = QHBoxLayout()
        bottom_layout.addWidget(self.rgb_radio)
        bottom_layout.addWidget(self.red_radio)
        bottom_layout.addWidget(self.green_radio)
        bottom_layout.addWidget(self.blue_radio)
        bottom_layout.addWidget(self.value_radio)
        bottom_layout.addWidget(self.log_check)
        bottom_layout.addWidget(self.grid_check)
        bottom_layout.addStretch()
        bottom_layout.addWidget(unique_label)

        main_layout = QVBoxLayout()
        main_layout.addLayout(center_layout)
        main_layout.addLayout(bottom_layout)
        self.setLayout(main_layout)
示例#21
0
class QFramelessWindow(QWidget):
    """
    无边框窗口类
    """
    def __init__(self):
        super(QFramelessWindow,
              self).__init__(None, Qt.FramelessWindowHint)  # 设置为顶级窗口,无边框

        # ----------------属性值------------#
        self._m_window_width = 1000  # type: int  # 默认窗口的宽度
        self._m_window_height = 900  # type: int  # 默认窗口的高度
        self._m_window_minimum_width = 250  # type: int  # 最小窗口宽度
        self._m_window_minimum_height = 200  # type: int  # 最小窗口高度
        self._m_padding = 5  # type: int  # 边界宽度
        self._m_title_text = '无边框窗口'  # type: str  # 窗口标题文字
        self._m_icon_path = ''  # type: str # 窗口图标所在的路径
        self._m_title_height = 60  # type: int  # 窗口标题栏的高度
        self._m_title_text_width = 40  # type: int  # 标题文字所占的宽度
        self._m_title_label = QTitleLabel(self)  # type: QTitleLabel  # 用于显示标题
        self._m_title_position = 0  # type: int  # 标题的相对位置:0 - 靠左,1 - 水平居中
        self._m_status_label = QStatusLabel(self)
        self._m_status_time_label = QStatusTimeLabel(self)  #  右下角显示日期时间的label

        # 设置鼠标跟踪判断扳机默认值
        self._m_move_drag = False
        self._m_corner_drag = False
        self._m_bottom_drag = False
        self._m_right_drag = False

        self._m_close_btn = None  # type: QTitleButton  # 右上角的关闭按钮
        self._m_minimum_btn = None  # type: QTitleButton  # 右上角的最小化按钮
        self._m_maximum_btn = None  # type: QTitleButton  # 右上角的最大化按钮,有两种状态:最大化、回复正常

        self._m_main_layout = QVBoxLayout()

        self.setMinimumSize(self._m_window_minimum_width,
                            self._m_window_minimum_height)
        # 设置窗口居中
        screen_w = QApplication.desktop().screenGeometry().width()
        screen_h = QApplication.desktop().screenGeometry().height()
        self.setGeometry((screen_w - self._m_window_width) / 2,
                         (screen_h - self._m_window_height) / 2,
                         self._m_window_width, self._m_window_height)
        self.setMouseTracking(True)  # 设置widget鼠标跟踪
        self._init_title_label()
        self._init_status_label()

    # -----------------API 接口--------------------------#
    def add_close_button(self):
        """
        在右上角添加关闭按钮
        :return:
        """
        self._m_close_btn = QTitleButton(b'\xef\x81\xb2'.decode("utf-8"), self)

        # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
        self._m_close_btn.setObjectName("CloseButton")
        self._m_close_btn.setToolTip("关闭窗口")
        # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
        self._m_close_btn.setMouseTracking(True)
        # 设置按钮高度为标题栏高度
        self._m_close_btn.setFixedHeight(self._m_title_height)
        # 按钮信号连接到关闭窗口的槽函数
        self._m_close_btn.clicked.connect(self.close)
        # self._m_close_btn.setStyleSheet("QPushButton{background: transparent;}")
        self._m_close_btn.setFlat(True)

    def add_minimum_button(self):
        """
        在右上角添加最小化按钮
        :return:
        """
        self._m_minimum_btn = QTitleButton(b'\xef\x80\xb0'.decode("utf-8"),
                                           self)
        self._m_minimum_btn.setObjectName(
            "MinMaxButton")  # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
        self._m_minimum_btn.setToolTip("最小化")
        self._m_minimum_btn.setMouseTracking(
            True)  # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
        self._m_minimum_btn.setFixedHeight(
            self._m_title_height)  # 设置按钮高度为标题栏高度
        self._m_minimum_btn.clicked.connect(
            self.showMinimized)  # 按钮信号连接到最小化窗口的槽函数
        self._m_minimum_btn.setFlat(True)

    def add_maximum_button(self):
        """
        在右上角添加最大化按钮
        :return:
        """
        self._m_maximum_btn = QTitleButton(b'\xef\x80\xb1'.decode("utf-8"),
                                           self)
        self._m_maximum_btn.setObjectName(
            "MinMaxButton")  # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
        self._m_maximum_btn.setToolTip("最大化")
        self._m_maximum_btn.setMouseTracking(
            True)  # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
        self._m_maximum_btn.setFixedHeight(
            self._m_title_height)  # 设置按钮高度为标题栏高度
        self._m_maximum_btn.clicked.connect(
            self._on_set_window_maximum)  # 按钮信号连接切换到恢复窗口大小按钮函数
        # self._m_maximum_btn.setStyleSheet("QPushButton{background: transparent;}")
        self._m_maximum_btn.setFlat(True)

    def set_window_title(self, title: str) -> None:
        """
        设置窗口的标题
        :param title:标题
        :return:
        """
        f = QFont(QFont('Microsoft YaHei', 14))
        fm = QFontMetrics(f)
        self._m_title_text_width = fm.width(title)
        self._m_title_label.setFont(f)
        self._m_title_label.setText(title)
        self._m_title_text = title
        self.setWindowTitle(title)
        self.update()

    def set_window_icon(self, icon_path: str) -> None:
        """
        设置窗口图标
        :param icon_path: 图标文件所在的路径
        :return:
        """
        self._m_icon_path = icon_path
        self.setWindowIcon(QIcon(icon_path))
        self.update()

    def set_window_title_height(self, height: int) -> None:
        """
        设置窗口标题栏的高度
        :param height: 标题栏高度
        :return: None
        """
        self._m_title_height = height
        self._init_title_label()
        self.set_window_title(self._m_title_text)
        self._m_close_btn.setFixedHeight(self._m_title_height)
        self._m_maximum_btn.setFixedHeight(self._m_title_height)
        self._m_minimum_btn.setFixedHeight(self._m_title_height)
        self.resize(self.size())
        self.update()

    def set_window_title_position(self, position: int) -> None:
        """
        设置标题的位置:1-靠右,2-水平居中
        :param position: 1或2
        :return:
        """
        self._m_title_position = position

    def set_layout(self, widget=None, layout=None) -> None:
        """
        向该无边框窗口中设置控件或布局,只能通过此函数添加控件或布局
        :param widget: 控件
        :param layout: 布局
        :return:
        """
        self._m_main_layout.setContentsMargins(0, 0, 0, 0)
        self._m_main_layout.setSpacing(0)
        self._m_main_layout.addSpacing(self._m_title_height)
        if widget:
            self._m_main_layout.addWidget(widget)
        if layout:
            self._m_main_layout.addLayout(layout)

        self._m_main_layout.addSpacing(self._m_status_label.height())

        self.setLayout(self._m_main_layout)

    def _init_title_label(self) -> None:
        """
        在主窗口界面上安放用于显示标题的label
        :return:
        """
        # 设置标题栏标签鼠标跟踪(如不设,则标题栏内在widget上层,无法实现跟踪)
        self._m_title_label.setMouseTracking(True)
        # 设置标题栏文本缩进
        self._m_title_label.setIndent(10)
        self._m_title_label.setFixedHeight(self._m_title_height)
        # 标题栏安放到左上角
        if self._m_title_position == 0:
            self._m_title_label.move(10, 0)
        else:
            self._m_title_label.move(
                (self.width() - self._m_title_text_width) / 2, 0)

    def set_status_text(self, str='状态栏'):
        self._m_status_label.setText(str)

    def _init_status_label(self):
        """
        创建状态栏
        :return:
        """
        self._m_status_label.setMouseTracking(True)

    # -------------槽函数-----------------#

    def _on_set_window_maximum(self):
        """
        点击了最大化按钮,将窗口最大化
        :return:
        """
        try:
            self.showMaximized()  # 先实现窗口最大化
            self._m_maximum_btn.setText(
                b'\xef\x80\xb2'.decode("utf-8"))  # 更改按钮文本
            self._m_maximum_btn.setToolTip("恢复")  # 更改按钮提示
            self._m_maximum_btn.clicked.disconnect()  # pyside2只能用这种方法
            # self._m_maximum_btn.disconnect()  # 断开原本的信号槽连接   pyqt5 中有效
            self._m_maximum_btn.clicked.connect(
                self._on_set_window_normal)  # 重新连接信号和槽
        except:
            pass

    def _on_set_window_normal(self):
        """
        点击了最大化按钮,将窗口恢复正常大小
        :return:
        """
        try:
            self.showNormal()
            self._m_maximum_btn.setText(b'\xef\x80\xb1'.decode("utf-8"))
            self._m_maximum_btn.setToolTip("最大化")
            self._m_maximum_btn.clicked.disconnect()  # pyside2只能用这种方法
            # self._m_maximum_btn.disconnect()    # pyqt5 中有效
            self._m_maximum_btn.clicked.connect(self._on_set_window_maximum)
        except:
            pass

    # -------------------重载事件响应函数--------------#
    def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
        """
        重载paintEvent函数
        :param a0:
        :return:
        """
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing)
        p.save()
        p.setPen(Qt.NoPen)

        lgt = QLinearGradient(QPointF(0, 0), QPointF(self.width(), 0))
        lgt.setColorAt(0.0, QColor('#511235'))
        lgt.setColorAt(1.0, QColor('red'))
        p.setBrush(lgt)
        p.drawRect(QRectF(0, 0, self.width(), self._m_title_height))
        p.drawRect(
            QRectF(0,
                   self.height() - self._m_status_label.height(),
                   self.rect().width(), self._m_status_label.height()))
        line_pen = QPen()
        line_pen.setColor(QColor(30, 144, 255, 30))
        line_pen.setWidth(1)
        p.setPen(line_pen)
        p.drawLine(0,
                   self.rect().height() - self._m_status_label.height(),
                   self.rect().width(),
                   self.rect().height() - self._m_status_label.height())

        # 在窗口左上角画图标

        if self._m_icon_path:
            imx = QPixmap(self._m_icon_path)
            p.drawPixmap(5, (self._m_title_label.height() - imx.height()) / 2,
                         imx)

        p.restore()

    def resizeEvent(self, QResizeEvent):
        # 将标题标签始终设为窗口宽度
        self._m_title_label.setFixedWidth(self._m_title_text_width * 2)
        if self._m_title_position == 0:
            if self._m_icon_path:
                imx = QPixmap(self._m_icon_path)
                self._m_title_label.move(imx.width() + 5, 0)
        else:
            self._m_title_label.move(
                (self.width() - self._m_title_text_width) / 2, 0)

        self._m_status_label.move(
            0,
            self.rect().height() - self._m_status_label.height())
        self._m_status_label.setFixedWidth(self.rect().width() -
                                           self._m_status_time_label.width())
        self._m_status_time_label.move(
            self._m_status_label.width(),
            self.rect().height() - self._m_status_label.height())
        # 分别移动三个按钮到正确的位置
        try:
            self._m_close_btn.move(
                self.width() - self._m_close_btn.width(),
                (self._m_title_height - self._m_close_btn.height()) / 2)
        except:
            pass
        try:
            self._m_minimum_btn.move(
                self.width() - (self._m_close_btn.width() + 1) * 3 + 1,
                (self._m_title_height - self._m_close_btn.height()) / 2 - 4)
        except:
            pass
        try:
            self._m_maximum_btn.move(
                self.width() - (self._m_close_btn.width() + 1) * 2 + 1,
                (self._m_title_height - self._m_close_btn.height()) / 2)
        except:
            pass
        # 重新调整边界范围以备实现鼠标拖放缩放窗口大小,采用三个列表生成式生成三个列表
        self._right_rect = [
            QPoint(x, y) for x in range(self.width() - self._m_padding,
                                        self.width() + 1)
            for y in range(1,
                           self.height() - self._m_padding)
        ]
        self._bottom_rect = [
            QPoint(x, y) for x in range(1,
                                        self.width() - self._m_padding)
            for y in range(self.height() - self._m_padding,
                           self.height() + 1)
        ]
        self._corner_rect = [
            QPoint(x, y) for x in range(self.width() - self._m_padding,
                                        self.width() + 1)
            for y in range(self.height() - self._m_padding,
                           self.height() + 1)
        ]

    def mouseDoubleClickEvent(self, event):
        if (event.button()
                == Qt.LeftButton) and (event.y() < self._m_title_height):
            # 鼠标左键双击标题栏区域,切换界面最大化和最小化
            windowstate = int(self.windowState())
            if windowstate == 0:
                self._on_set_window_maximum()
            elif windowstate == 2:
                self._on_set_window_normal()

            event.accept()

    def mousePressEvent(self, event):
        # 重写鼠标点击的事件
        if (event.button() == Qt.LeftButton) and (event.pos()
                                                  in self._corner_rect):
            # 鼠标左键点击右下角边界区域
            self._m_corner_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._right_rect):
            # 鼠标左键点击右侧边界区域
            self._m_right_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._bottom_rect):
            # 鼠标左键点击下侧边界区域
            self._m_bottom_drag = True
            event.accept()
        elif (event.button()
              == Qt.LeftButton) and (event.y() < self._m_title_height):
            # 鼠标左键点击标题栏区域
            self._m_move_drag = True
            self.move_DragPosition = event.globalPos() - self.pos()
            event.accept()

    def mouseMoveEvent(self, QMouseEvent):
        # 判断鼠标位置切换鼠标手势
        if QMouseEvent.pos() in self._corner_rect:
            self.setCursor(Qt.SizeFDiagCursor)
        elif QMouseEvent.pos() in self._bottom_rect:
            self.setCursor(Qt.SizeVerCursor)
        elif QMouseEvent.pos() in self._right_rect:
            self.setCursor(Qt.SizeHorCursor)
        else:
            self.setCursor(Qt.ArrowCursor)
        # 当鼠标左键点击不放及满足点击区域的要求后,分别实现不同的窗口调整
        # 没有定义左方和上方相关的5个方向,主要是因为实现起来不难,但是效果很差,拖放的时候窗口闪烁,再研究研究是否有更好的实现
        if Qt.LeftButton and self._m_right_drag:
            # 右侧调整窗口宽度
            self.resize(QMouseEvent.pos().x(), self.height())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._m_bottom_drag:
            # 下侧调整窗口高度
            self.resize(self.width(), QMouseEvent.pos().y())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._m_corner_drag:
            # 右下角同时调整高度和宽度
            self.resize(QMouseEvent.pos().x(), QMouseEvent.pos().y())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._m_move_drag:
            # 标题栏拖放窗口位置
            self.move(QMouseEvent.globalPos() - self.move_DragPosition)
            QMouseEvent.accept()

    def mouseReleaseEvent(self, a0: QtGui.QMouseEvent) -> None:
        """
        重载 mouseReleaseEvent 函数
        鼠标释放后,各扳机复位
        :param a0: 事件,没有用上
        :return: None
        """
        self._m_move_drag = False
        self._m_corner_drag = False
        self._m_bottom_drag = False
        self._m_right_drag = False
示例#22
0
class MainWindow(QMainWindow):
    def __init__(self, app):
        super(MainWindow, self).__init__()
        self.app = app
        self.central_widget_setup()
        self.default_vbox_setup()
        self.layout.addWidget(PrimaryMonitorSelect(self))
        self.add_application_button_setup()
        self.application_boxes_setup()
        self.application_grid_setup()
        self.application_scroll_setup()
        self.window_setup()

    def window_setup(self):
        self.adjustSize()
        self.setGeometry(
            QStyle.alignedRect(
                Qt.LeftToRight,
                Qt.AlignCenter,
                self.size(),
                QGuiApplication.primaryScreen().availableGeometry(),
            ))
        self.setWindowTitle("Saharah Paper")
        self.setWindowIcon(QIcon(f"{sys.argv[0]}/assets/app_icon.png"))

    def central_widget_setup(self):
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignCenter | Qt.AlignTop)
        self.centralWidget.setLayout(self.layout)

    def default_vbox_setup(self):
        self.defaultVBox = QHBoxLayout()
        self.defaultVBox.addWidget(WallpaperBox(self, 0, True))
        self.defaultVBox.addWidget(WallpaperBox(self, 1, True))
        self.layout.addLayout(self.defaultVBox)

    def add_application_button_setup(self):
        self.addApplicationButton = AddApplicationButton(self)
        self.layout.addWidget(self.addApplicationButton,
                              alignment=Qt.AlignCenter)

    def application_boxes_setup(self):
        self.applicationBoxes = list()
        for i in range(0, len(applicationSettings.list)):
            self.applicationBoxes.append(WallpaperBox(self, i))

    def application_grid_setup(self):
        self.applicationGrid = QVBoxLayout()
        self.applicationGridContainer = QWidget()
        self.applicationGridContainer.setLayout(self.applicationGrid)
        self.applicationGridContainer.setFixedWidth(1340)
        self.application_grid_arrange()

    def application_grid_arrange(self):
        for i in reversed(range(0, self.applicationGrid.count())):
            layout = self.applicationGrid.itemAt(i).layout()
            for j in reversed(range(0, layout.count())):
                widget = layout.itemAt(j).widget()
                widget.hide()
        for i in range(0, len(self.applicationBoxes)):
            r = math.floor((i) / 4)
            item = self.applicationGrid.itemAt(r)
            if item is None:
                layout = QHBoxLayout()
                layout.setAlignment(Qt.AlignLeft | Qt.AlignTop)
                self.applicationGrid.addLayout(layout)
            else:
                layout = item.layout()
            applicationBox = self.applicationBoxes[i]
            applicationBox.set_index(i)
            applicationBox.show()
            layout.addWidget(applicationBox)
        self.applicationGridContainer.setFixedHeight(
            self.applicationGrid.count() * 250)

    def application_scroll_setup(self):
        self.applicationScroll = QScrollArea()
        self.applicationScroll.setWidget(self.applicationGridContainer)
        self.applicationScroll.setFixedSize(1370, 510)
        self.layout.addWidget(self.applicationScroll)

    def closeEvent(self, event):
        self.app.mainWindow.hide()
        event.accept()
示例#23
0
 def _add_grouped(self, form, title, widget):
     box = QGroupBox(title)
     vbox = QVBoxLayout()
     vbox.addWidget(widget)
     box.setLayout(vbox)
     form.addRow(box)
示例#24
0
    def _set_labels_and_layout(self):
        """
        Creates this Widget's content and layout
        """
        # --- Content ---

        # Lecluse DevCorp. Logo
        logo = QLabel()
        logo.setPixmap(QPixmap("assets/LDC-dark.png"))
        logo.setFixedSize(QSize(
            512, 222))  # Original dimension is 2048x888, we divided by 4
        logo.setScaledContents(True)

        # App credo
        lab_app = QLabel(f'<b>{tr("app_title")}</b> {tr("about_sdc")}')

        # Devs
        features_lab = QLabel(tr("about_features"))
        ihm_lab = QLabel(tr("about_ihm"))
        web_lab = QLabel(tr("about_web"))
        features_dev = QLabel(
            f'{self.links_style}<a href="https://www.lecluse.fr">Olivier Lécluse</a>'
        )
        features_dev.setOpenExternalLinks(True)
        ihm_dev = QLabel(
            f'{self.links_style}<a href="https://www.linkedin.com/in/thomas-lécluse-62130395/">Thomas Lécluse</a>'
        )
        ihm_dev.setOpenExternalLinks(True)
        web_dev = QLabel(
            f'{self.links_style}<a href="https://www.linkedin.com/in/nicolas-lecluse-a3488752/">Nicolas Lécluse</a>'
        )
        web_dev.setOpenExternalLinks(True)

        # Documentation link
        lab_link_doc = QLabel(
            f'{tr("link_to")} {self.links_style}<a href="https://sdc.lecluse.fr">{tr("about_doc")}</a>'
        )
        lab_link_doc.setOpenExternalLinks(True)

        # Github link
        lab_link_git = QLabel(
            f'{tr("link_to")} {self.links_style}<a href="https://github.com/wawachief/SalleDeClasse">{tr("about_github")}</a>'
        )
        lab_link_git.setOpenExternalLinks(True)

        # Contact
        lab_contact = QLabel(
            f'{tr("about_contact")} {self.links_style}<a href="mailto:[email protected]">[email protected]</a>'
        )
        lab_contact.setOpenExternalLinks(True)

        # License
        lab_license = QLabel(
            f'{self.links_style}<a href="https://www.gnu.org/licenses/gpl-3.0.fr.html">GPL-3.0 License</a>'
        )
        lab_license.setOpenExternalLinks(True)

        # Version
        lab_app_version = QLabel(tr("app_version"))
        lab_bdd_version = QLabel(tr("bdd_version"))
        app_version = QLabel(AssetManager.getInstance().config(
            'main', 'version'))
        bdd_version = QLabel(str(self.bdd_version))

        # --- Layout ---
        box = QVBoxLayout()
        box.setMargin(0)
        box.setSpacing(0)

        # Logo
        box.addWidget(logo, alignment=Qt.AlignCenter)

        Separator(self.width(), box)  # ----

        # 'Salle de Classe' credo
        box.addWidget(lab_app, alignment=Qt.AlignCenter)
        box.addSpacing(SPACING_SIZE)

        # Devs roles
        dev_grid = QGridLayout()
        dev_grid.setContentsMargins(0, 0, 0, 0)
        dev_grid.addWidget(features_lab, 0, 0, alignment=Qt.AlignRight)
        dev_grid.addWidget(ihm_lab, 1, 0, alignment=Qt.AlignRight)
        dev_grid.addWidget(web_lab, 2, 0, alignment=Qt.AlignRight)
        dev_grid.addWidget(features_dev, 0, 1, alignment=Qt.AlignLeft)
        dev_grid.addWidget(ihm_dev, 1, 1, alignment=Qt.AlignLeft)
        dev_grid.addWidget(web_dev, 2, 1, alignment=Qt.AlignLeft)
        box.addLayout(dev_grid)

        # Contact
        box.addSpacing(SPACING_SIZE)
        box.addWidget(lab_contact, alignment=Qt.AlignCenter)

        Separator(self.width(), box)  # ----

        # Links of doc, git and license
        box.addWidget(lab_link_doc, alignment=Qt.AlignCenter)
        box.addWidget(lab_link_git, alignment=Qt.AlignCenter)
        box.addSpacing(SPACING_SIZE)
        box.addWidget(lab_license, alignment=Qt.AlignCenter)

        Separator(self.width(), box)  # ----

        # Version
        grid_version = QGridLayout()
        grid_version.addWidget(lab_app_version, 0, 0, alignment=Qt.AlignRight)
        grid_version.addWidget(lab_bdd_version, 1, 0, alignment=Qt.AlignRight)
        grid_version.addWidget(app_version, 0, 1, alignment=Qt.AlignLeft)
        grid_version.addWidget(bdd_version, 1, 1, alignment=Qt.AlignLeft)
        box.addLayout(grid_version)
        box.addSpacing(SPACING_SIZE)

        self.setLayout(box)
示例#25
0
    def __init__(self, mode, parentQWidget = None):
        QVBoxLayout.__init__(self)

        self.sig.connect(self.addThreadList)
        self.mode = mode

        self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)

        self.groupBoxSearch = QGroupBox()
        self.groupBoxSearch.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 4px; };")
        vboxSearch = QVBoxLayout()
        self.searchTitle = QLabel("Search Messages")
        vboxSearch.addWidget(self.searchTitle)
        self.searchHLayout = QHBoxLayout()
        self.editTextSearch = QTextEdit('')
        self.editTextSearch.setFixedSize(200,30)
        self.buttonSearch = QPushButton('Search')
        self.buttonSearch.setFixedSize(100,30)
        self.buttonSearch.clicked.connect(self.searchMsg)
        vboxSearch.addWidget(self.editTextSearch)
        self.searchHLayout.addWidget(self.buttonSearch)
        self.searchCursor = QLabel()
        self.searchHLayout.addWidget(self.searchCursor)
        vboxSearch.addLayout(self.searchHLayout)
        self.browseHLayout = QHBoxLayout()
        self.buttonLookUp = QPushButton('\u21e7')  #Arrow up
        self.buttonLookUp.setFixedWidth(100)
        self.buttonLookUp.clicked.connect(self.moveToPrev)
        self.buttonLookDown = QPushButton('\u21e9') #Arrow down
        self.buttonLookDown.setFixedWidth(100)
        self.buttonLookDown.clicked.connect(self.moveToNext)
        self.browseHLayout.addWidget(self.buttonLookUp)
        self.browseHLayout.addWidget(self.buttonLookDown)
        vboxSearch.addLayout(self.browseHLayout)
        self.groupBoxSearch.setLayout(vboxSearch)
        self.addWidget(self.groupBoxSearch)
        self.groupBoxSearch.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.buttonHiddenLifelines = QPushButton('Show hidden life-lines')
        self.buttonHiddenLifelines.setFixedWidth(200)
        self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines)
        self.addWidget(self.buttonHiddenLifelines)

        self.buttonHiddenMessages = QPushButton('Show hidden Messages')
        self.buttonHiddenMessages.setFixedWidth(200)
        self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages)
        self.addWidget(self.buttonHiddenMessages)

        if const.mode_interactive == mode:
            self.buttonCapture = QPushButton('Capture')
            self.buttonCapture.setFixedWidth(200)
            self.buttonCapture.clicked.connect(self.notifyCapture)
            self.addWidget(self.buttonCapture)
        self.msgRcv = []
        self.msgInfo = QLabel("Message Info.")
        self.groupBoxMessageInfo = QGroupBox()
        self.groupBoxMessageInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;")
        vbox = QVBoxLayout()
        vbox.addWidget(self.msgInfo)
        self.tableTime = QTableWidget(3,2)
        self.tableTime.setHorizontalHeaderLabels(['-','time'])
        self.tableTime.setColumnWidth(0,80)
        self.tableTime.setColumnWidth(1,150)
        vwidth = self.tableTime.verticalHeader().length()
        hwidth = self.tableTime.horizontalHeader().height()
        fwidth = self.tableTime.frameWidth() * 2
        self.tableTime.setFixedHeight(vwidth + hwidth + fwidth)
        self.tableTime.horizontalHeader().setStretchLastSection(True)
        self.tableTime.setItem(0,0,QTableWidgetItem('begin'))
        self.tableTime.setItem(0,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(1,0,QTableWidgetItem('end'))
        self.tableTime.setItem(1,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(2,0,QTableWidgetItem('duration'))
        self.tableTime.setItem(2,1,QTableWidgetItem(' - '))
        vbox.addWidget(self.tableTime)

        self.titleArg = QLabel('Argument List')
        vbox.addWidget(self.titleArg)

        max_arg_num = 10
        self.tableArgs = QTableWidget(max_arg_num,2)
        self.tableArgs.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_arg_num):
            self.tableArgs.setItem(idx,0,QTableWidgetItem())
            self.tableArgs.setItem(idx,1,QTableWidgetItem())
        self.tableArgs.horizontalHeader().setStretchLastSection(True)
        vbox.addWidget(self.tableArgs)

        self.titleArg = QLabel('Return Value List')
        vbox.addWidget(self.titleArg)

        max_ret_num = 4
        self.tableRet = QTableWidget(max_ret_num,2)
        self.tableRet.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_ret_num):
            self.tableRet.setItem(idx,0,QTableWidgetItem())
            self.tableRet.setItem(idx,1,QTableWidgetItem())
        self.tableRet.horizontalHeader().setStretchLastSection(True)
        vwidth = self.tableRet.verticalHeader().length()
        hwidth = self.tableRet.horizontalHeader().height()
        fwidth = self.tableRet.frameWidth() * 2
        self.tableRet.setFixedHeight(vwidth + hwidth + fwidth)
        vbox.addWidget(self.tableRet)

        self.buttonSrcView = QPushButton('view code')
        self.buttonSrcView.setFixedWidth(200)
        self.buttonSrcView.clicked.connect(self.openSourceViewer)
        self.buttonHide = QPushButton('Hide')
        self.buttonHide.setFixedWidth(200)
        self.buttonHide.clicked.connect(self.notifyHide)
        self.buttonHideAllMsg = QPushButton('Hide All')
        self.buttonHideAllMsg.setFixedWidth(200)
        self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected)
        self.groupBoxMessageInfo.setLayout(vbox)
        self.checkHideCircular = QCheckBox('Hide Circular Messages')
        self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked)
        self.checkHideCircular.stateChanged.connect(self.changeHideCircularMessage)
        self.addWidget(self.checkHideCircular)
        self.addWidget(self.groupBoxMessageInfo)
        self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy)
class MyDockWidget(cutter.CutterDockWidget):
    def __init__(self, parent, action):
        super(MyDockWidget, self).__init__(parent, action)
        self.setObjectName("Capa explorer")
        self.setWindowTitle("Capa explorer")

        self._config = CutterBindings.Configuration.instance()
        self.model_data = CapaExplorerDataModel()

        self.range_model_proxy = CapaExplorerRangeProxyModel()
        self.range_model_proxy.setSourceModel(self.model_data)
        self.search_model_proxy = CapaExplorerSearchProxyModel()
        self.search_model_proxy.setSourceModel(self.range_model_proxy)

        self.create_view_tabs()
        self.create_menu()
        self.create_tree_tab_ui()
        self.create_view_attack()

        self.connect_signals()
        self.setWidget(self.tabs)
        self.show()

    def create_view_tabs(self):

        # Create tabs container
        self.tabs = QTabWidget()

        # Create the tabs
        self.tab_attack = QWidget(self.tabs)
        self.tab_tree_w_model = QWidget(self.tabs)

        self.tabs.addTab(self.tab_tree_w_model, "Tree View")
        self.tabs.addTab(self.tab_attack, "MITRE")

    def create_menu(self):
        # Define menu actions
        # Text, tooltip, function, enabled before file load
        self.disabled_menu_items = []

        menu_actions = [
            ("Load JSON file", '', self.cma_load_file, True),
            (),
            ("Auto rename functions",
             'Auto renames functions according to capa detections, can result in very long function names.',
             self.cma_analyze_and_rename, False),
            ("Create flags",
             'Creates flagspaces and flags from capa detections.',
             self.cma_create_flags, False),
            (),
            ("About", '', self.cma_display_about, True),
        ]

        self.capa_menu = QMenu()
        self.capa_menu.setToolTipsVisible(True)

        # Create qactions
        for action in menu_actions:
            if not len(action):
                # Create separator on empty
                self.capa_menu.addSeparator()
                continue

            a = QAction(self)
            a.setText(action[0])
            a.setToolTip(action[1])
            a.triggered.connect(action[2])
            a.setEnabled(action[3])
            if not action[3]:
                self.disabled_menu_items.append(a)
            self.capa_menu.addAction(a)

            # Create menu button
            font = QFont()
            font.setBold(True)
            self.btn_menu = QToolButton()
            self.btn_menu.setText('...')
            self.btn_menu.setFont(font)
            self.btn_menu.setPopupMode(QToolButton.InstantPopup)
            self.btn_menu.setMenu(self.capa_menu)
            self.btn_menu.setStyleSheet(
                'QToolButton::menu-indicator { image: none; }')
            self.tabs.setCornerWidget(self.btn_menu, corner=Qt.TopRightCorner)

    def create_tree_tab_ui(self):
        self.capa_tree_view_layout = QVBoxLayout()
        self.capa_tree_view_layout.setAlignment(Qt.AlignTop)

        self.chk_fcn_scope = QCheckBox("Limit to Current function")
        #TODO: reset state on load file
        self.chk_fcn_scope.setChecked(False)
        self.chk_fcn_scope.stateChanged.connect(
            self.slot_checkbox_limit_by_changed)

        self.input_search = QLineEdit()
        self.input_search.setStyleSheet("margin:0px; padding:0px;")
        self.input_search.setPlaceholderText("search...")
        self.input_search.textChanged.connect(
            self.slot_limit_results_to_search)

        self.filter_controls_container = QGroupBox()
        self.filter_controls_container.setObjectName("scope")
        self.filter_controls_container.setFlat(True)
        self.filter_controls_container.setStyleSheet(
            "#scope{border:0px; padding:0px; margin:0px;subcontrol-origin: padding; subcontrol-position: left top;}"
        )
        self.filter_controls_layout = QHBoxLayout(
            self.filter_controls_container)
        self.filter_controls_layout.setContentsMargins(0, 0, 0, 0)
        self.filter_controls_layout.addWidget(self.input_search)
        self.filter_controls_layout.addWidget(self.chk_fcn_scope)

        self.view_tree = CapaExplorerQtreeView(self.search_model_proxy)
        self.view_tree.setModel(self.search_model_proxy)

        # Make it look a little nicer when no results are loaded
        self.view_tree.header().setStretchLastSection(True)

        self.capa_tree_view_layout.addWidget(self.filter_controls_container)
        self.capa_tree_view_layout.addWidget(self.view_tree)
        self.tab_tree_w_model.setLayout(self.capa_tree_view_layout)

    def create_view_attack(self):
        table_headers = [
            "ATT&CK Tactic",
            "ATT&CK Technique ",
        ]
        table = QTableWidget()
        table.setColumnCount(len(table_headers))
        table.verticalHeader().setVisible(False)
        table.setSortingEnabled(False)
        table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        table.setFocusPolicy(Qt.NoFocus)
        table.setSelectionMode(QAbstractItemView.NoSelection)
        table.setHorizontalHeaderLabels(table_headers)
        table.horizontalHeader().setDefaultAlignment(Qt.AlignLeft)
        table.horizontalHeader().setStretchLastSection(True)
        table.setShowGrid(False)
        table.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
        #table.setStyleSheet("QTableWidget::item { padding: 25px; }")

        attack_view_layout = QVBoxLayout()
        attack_view_layout.setAlignment(Qt.AlignTop)

        self.attack_table = table

        attack_view_layout.addWidget(self.attack_table)
        self.tab_attack.setLayout(attack_view_layout)

        return table

    def connect_signals(self):

        QObject.connect(cutter.core(), SIGNAL("functionRenamed(RVA, QString)"),
                        self.model_data.refresh_function_names)
        QObject.connect(cutter.core(), SIGNAL("functionsChanged()"),
                        self.model_data.refresh_function_names)
        QObject.connect(cutter.core(), SIGNAL("seekChanged(RVA)"),
                        self.signal_shim_slot_checkbox_limit_by_changed)

    def render_new_table_header_item(self, text):
        """create new table header item with our style
        @param text: header text to display
        """
        item = QTableWidgetItem(text)
        item.setForeground(self._config.getColor("graph.true"))
        font = QFont()
        font.setBold(True)
        item.setFont(font)
        return item

    def fill_attack_table(self, rules):
        tactics = collections.defaultdict(set)
        for key, rule in rules.items():
            if not rule["meta"].get("att&ck"):
                continue

            for attack in rule["meta"]["att&ck"]:
                tactic, _, rest = attack.partition("::")
            if "::" in rest:
                technique, _, rest = rest.partition("::")
                subtechnique, _, id = rest.rpartition(" ")
                tactics[tactic].add((technique, subtechnique, id))
            else:
                technique, _, id = rest.rpartition(" ")
                tactics[tactic].add((technique, id))

        column_one = []
        column_two = []

        for (tactic, techniques) in sorted(tactics.items()):
            column_one.append(tactic.upper())
            # add extra space when more than one technique
            column_one.extend(["" for i in range(len(techniques) - 1)])

            for spec in sorted(techniques):
                if len(spec) == 2:
                    technique, id = spec
                    column_two.append("%s %s" % (technique, id))
                elif len(spec) == 3:
                    technique, subtechnique, id = spec
                    column_two.append("%s::%s %s" %
                                      (technique, subtechnique, id))
                else:
                    raise RuntimeError("unexpected ATT&CK spec format")

        self.attack_table.setRowCount(max(len(column_one), len(column_two)))

        for (row, value) in enumerate(column_one):
            self.attack_table.setItem(row, 0,
                                      self.render_new_table_header_item(value))

        for (row, value) in enumerate(column_two):
            self.attack_table.setItem(row, 1, QTableWidgetItem(value))

    def enable_menu_items_after_load(self):
        # enables menu actions after file is loaded
        for action in self.disabled_menu_items:
            action.setEnabled(True)

    def slot_limit_results_to_search(self, text):
        """limit tree view results to search matches
        reset view after filter to maintain level 1 expansion
        """
        self.search_model_proxy.set_query(text)
        self.view_tree.reset_ui(should_sort=False)

    def signal_shim_slot_checkbox_limit_by_changed(self):
        if self.chk_fcn_scope.isChecked():
            self.slot_checkbox_limit_by_changed(Qt.Checked)

    def slot_checkbox_limit_by_changed(self, state):
        """slot activated if checkbox clicked
        if checked, configure function filter if screen location is located in function, otherwise clear filter
        @param state: checked state
        """
        invoke_reset = True

        if state == Qt.Checked:
            minbound, maxbound = util.get_function_boundries_at_current_location(
            )

            if self.range_model_proxy.min_ea == minbound and self.range_model_proxy.max_ea == maxbound:
                # Seek only changed within current function, avoid resetting tree
                invoke_reset = False

            self.limit_results_to_function((minbound, maxbound))
        else:
            self.range_model_proxy.reset_address_range_filter()

        if invoke_reset:
            self.view_tree.reset_ui()

    def limit_results_to_function(self, f):
        """add filter to limit results to current function
        adds new address range filter to include function bounds, allowing basic blocks matched within a function
        to be included in the results
        @param f: (tuple (maxbound, minbound))
        """
        if f:
            self.range_model_proxy.add_address_range_filter(f[0], f[1])
        else:
            # if function not exists don't display any results (assume address never -1)
            self.range_model_proxy.add_address_range_filter(-1, -1)

    # --- Menu Actions

    def cma_analyze_and_rename(self):
        message_box = QMessageBox()

        message_box.setStyleSheet("QLabel{min-width: 370px;}")
        message_box.setStandardButtons(QMessageBox.Cancel | QMessageBox.Ok)
        message_box.setEscapeButton(QMessageBox.Cancel)
        message_box.setDefaultButton(QMessageBox.Ok)

        message_box.setWindowTitle('Warning')
        message_box.setText(
            'Depending on the size of the binary and the'
            ' amount of \n'
            'capa matches this feature can take some time to \n'
            'complete and might make the UI freeze temporarily.')
        message_box.setInformativeText('Are you sure you want to proceed ?')

        ret = message_box.exec_()

        # Ok = 1024
        if ret == 1024:
            self.model_data.auto_rename_functions()

    def cma_create_flags(self):
        self.model_data.create_flags()

    def cma_display_about(self):
        c = CAPAExplorerPlugin()

        info_text = ("{description}\n\n"
                     "https://github.com/ninewayhandshake/capa-explorer\n\n"
                     "Version: {version}\n"
                     "Author: {author}\n"
                     "License: Apache License 2.0\n").format(
                         version=c.version,
                         author=c.author,
                         description=c.description,
                     )

        text = CAPAExplorerPlugin().name
        message_box = QMessageBox()
        message_box.setStyleSheet("QLabel{min-width: 370px;}")

        message_box.setWindowTitle('About')
        message_box.setText(text)
        message_box.setInformativeText(info_text)
        message_box.setStandardButtons(QMessageBox.Close)

        for i in message_box.findChildren(QLabel):
            i.setFocusPolicy(Qt.NoFocus)

        message_box.exec_()

    def cma_load_file(self):

        filename = QFileDialog.getOpenFileName()
        path = filename[0]

        if len(path):
            try:
                data = util.load_capa_json(path)

                self.fill_attack_table(data['rules'])
                self.model_data.clear()
                self.model_data.render_capa_doc(data)

                # Restore ability to scroll on last column
                self.view_tree.header().setStretchLastSection(False)

                self.view_tree.slot_resize_columns_to_content()
                self.enable_menu_items_after_load()
            except Exception as e:
                util.log('Could not load json file.')
        else:
            util.log('No file selected.')
示例#27
0
        urllib.request.urlretrieve(url, target)
        print('done')
        dlg.close()

    def reject():
        exit(0)

    buttonBox = QDialogButtonBox(QBtn)
    buttonBox.accepted.connect(accept)
    buttonBox.rejected.connect(reject)

    layout = QVBoxLayout()
    label = QLabel(dlg)
    label.setText(
        f'Equilibrium core (pyo3d) was not found on your system.\nNo problem, we can download it automatically\n\nFile will be downloaded from:\n{url} \n\nand will be saved as:\n{target}'
    )
    layout.addWidget(label)

    link = QLabel(dlg)
    link.setText(
        '<a href="https://www.open-ocean.org/equilibrium-core/">More info: https://www.open-ocean.org/equilibrium-core/ </a>'
    )
    link.setOpenExternalLinks(True)
    layout.addWidget(link)

    layout.addWidget(buttonBox)
    dlg.setLayout(layout)
    dlg.exec_()

    import pyo3d
示例#28
0
    def __init__(self, image, parent=None):
        super(AdjustWidget, self).__init__(parent)

        self.bright_slider = ParamSlider([-255, +255], 16, 0)
        self.sat_slider = ParamSlider([-255, +255], 16, 0)
        self.hue_slider = ParamSlider([0, 180], 10, 0, '°')
        self.gamma_slider = ParamSlider([1, 50], 10, 10)
        self.shadow_slider = ParamSlider([-100, +100], 10, 0, '%')
        self.high_slider = ParamSlider([-100, +100], 10, 0, '%')
        self.sweep_slider = ParamSlider([0, 255], 8, 127)
        self.width_slider = ParamSlider([0, 255], 8, 255)
        self.sharpen_slider = ParamSlider([0, 100], 10, 0, '%')
        self.thr_slider = ParamSlider([0, 255],
                                      16,
                                      255,
                                      special=self.tr('Auto'))
        self.equalize_combo = QComboBox()
        self.equalize_combo.addItems([
            self.tr('No EQ'),
            self.tr('Hist EQ'),
            self.tr('CLAHE L1'),
            self.tr('CLAHE L2'),
            self.tr('CLAHE L3'),
            self.tr('CLAHE L4')
        ])
        self.equalize_combo.setToolTip(self.tr('Histogram equalization mode'))
        self.invert_check = QCheckBox(self.tr('Invert values'))
        self.invert_check.setToolTip(self.tr('Apply bitwise complement'))
        self.reset_button = QPushButton(self.tr('Reset'))

        self.image = image
        self.viewer = ImageViewer(self.image, self.image)
        self.reset()

        self.bright_slider.valueChanged.connect(self.process)
        self.sat_slider.valueChanged.connect(self.process)
        self.hue_slider.valueChanged.connect(self.process)
        self.gamma_slider.valueChanged.connect(self.process)
        self.shadow_slider.valueChanged.connect(self.process)
        self.high_slider.valueChanged.connect(self.process)
        self.sweep_slider.valueChanged.connect(self.process)
        self.width_slider.valueChanged.connect(self.process)
        self.thr_slider.valueChanged.connect(self.process)
        self.sharpen_slider.valueChanged.connect(self.process)
        self.equalize_combo.currentIndexChanged.connect(self.process)
        self.invert_check.stateChanged.connect(self.process)
        self.reset_button.clicked.connect(self.reset)

        params_layout = QGridLayout()
        params_layout.addWidget(QLabel(self.tr('Brightness')), 0, 0)
        params_layout.addWidget(QLabel(self.tr('Saturation')), 1, 0)
        params_layout.addWidget(QLabel(self.tr('Hue')), 2, 0)
        params_layout.addWidget(QLabel(self.tr('Gamma')), 3, 0)
        params_layout.addWidget(self.bright_slider, 0, 1)
        params_layout.addWidget(self.sat_slider, 1, 1)
        params_layout.addWidget(self.hue_slider, 2, 1)
        params_layout.addWidget(self.gamma_slider, 3, 1)
        params_layout.addWidget(QLabel(self.tr('Shadows')), 0, 2)
        params_layout.addWidget(QLabel(self.tr('Highlights')), 1, 2)
        params_layout.addWidget(QLabel(self.tr('Sweep')), 2, 2)
        params_layout.addWidget(QLabel(self.tr('Width')), 3, 2)
        params_layout.addWidget(self.shadow_slider, 0, 3)
        params_layout.addWidget(self.high_slider, 1, 3)
        params_layout.addWidget(self.sweep_slider, 2, 3)
        params_layout.addWidget(self.width_slider, 3, 3)
        params_layout.addWidget(QLabel(self.tr('Sharpen')), 0, 4)
        params_layout.addWidget(self.sharpen_slider, 0, 5)
        params_layout.addWidget(QLabel(self.tr('Threshold')), 1, 4)
        params_layout.addWidget(self.thr_slider, 1, 5)
        params_layout.addWidget(self.equalize_combo, 2, 4)
        params_layout.addWidget(self.invert_check, 2, 5)
        params_layout.addWidget(self.reset_button, 3, 4, 1, 2)

        main_layout = QVBoxLayout()
        main_layout.addLayout(params_layout)
        main_layout.addWidget(self.viewer)
        self.setLayout(main_layout)
示例#29
0
    def __init__(self, targetImage=None, axeSize=500, layer=None, parent=None):
        super().__init__(layer=layer, targetImage=targetImage, parent=parent)
        # options
        self.options = None
        # exposure slider
        self.sliderExp = QbLUeSlider(Qt.Horizontal)
        self.sliderExp.setStyleSheet(QbLUeSlider.bLueSliderDefaultBWStylesheet)
        self.sliderExp.setRange(-20, 20)
        self.sliderExp.setSingleStep(1)

        expLabel = QbLUeLabel()
        expLabel.setMaximumSize(150, 30)
        expLabel.setText("Exposure Correction")
        expLabel.doubleClicked.connect(
            lambda: self.sliderExp.setValue(self.defaultExpCorrection))

        self.expValue = QbLUeLabel()
        font = self.expValue.font()
        metrics = QFontMetrics(font)
        w = metrics.width("1000 ")
        h = metrics.height()
        self.expValue.setMinimumSize(w, h)
        self.expValue.setMaximumSize(w, h)

        # exp change/released slot
        def f():
            self.expValue.setText(
                str("{:+.1f}".format(self.sliderExp.value() *
                                     self.defaultStep)))
            if self.sliderExp.isSliderDown() or (self.expCorrection
                                                 == self.sliderExp.value() *
                                                 self.defaultStep):
                return
            try:
                self.sliderExp.valueChanged.disconnect()
                self.sliderExp.sliderReleased.disconnect()
            except RuntimeError:
                pass
            self.expCorrection = self.sliderExp.value() * self.defaultStep
            self.dataChanged.emit()
            self.sliderExp.valueChanged.connect(f)
            self.sliderExp.sliderReleased.connect(f)

        self.sliderExp.valueChanged.connect(f)
        self.sliderExp.sliderReleased.connect(f)

        # layout
        l = QVBoxLayout()
        l.setAlignment(Qt.AlignTop)
        l.addWidget(expLabel)
        hl = QHBoxLayout()
        hl.addWidget(self.expValue)
        hl.addWidget(self.sliderExp)
        l.addLayout(hl)
        l.setContentsMargins(20, 0, 20, 25)  # left, top, right, bottom
        self.setLayout(l)
        self.adjustSize()
        self.setWhatsThis("""<b>Exposure Correction</b>
                        Multiplicative correction in the linear sRGB color space.<br>
                        Unit is the diaphragm stop.<br>
                        """)  # end setWhatsThis

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

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

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

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

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

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

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

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

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

    """Algorytm DNF"""

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

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

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

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

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

    def get_solution(self, h, fail):
        if fail == 1:
            self.result.setText("Brak rozwiązania")
        else:
            self.result.setText("Rozwiązanie:\n\nh= (" + ") v (".join(h) + ")")
示例#31
0
    def __init__(self):
        super().__init__()
        # Título da janela.
        self.setWindowTitle('PySide2 QMessageBox().')

        # Ícone da janela principal
        icon = QIcon()
        icon.addPixmap(QPixmap('../../../images/icons/icon.png'))
        self.setWindowIcon(icon)

        # Tamanho inicial da janela.
        screen_size = app.desktop().geometry()
        # screen_size = app.primaryScreen().geometry()
        width = screen_size.width()
        height = screen_size.height()
        self.resize(width / 2, height / 2)

        # Tamanho mínimo da janela.
        self.setMinimumSize(width / 2, height / 2)

        # Tamanho maximo da janela.
        self.setMaximumSize(width - 200, height - 200)

        # Widgets.
        vbox = QVBoxLayout()
        self.setLayout(vbox)

        self.label = QLabel('Clique no botão para abrir o diálogo.')
        self.label.setAutoFillBackground(True)
        self.label.setAlignment(Qt.AlignCenter)
        vbox.addWidget(self.label)

        btn_dialog = QPushButton('Abrir diálogo do tipo caixa de mensagem')
        btn_dialog.clicked.connect(self.open_dialog)
        vbox.addWidget(btn_dialog)

        btn_dialog_about = QPushButton('Abrir diálogo do tipo sobre (about)')
        btn_dialog_about.clicked.connect(self.open_dialog_about)
        vbox.addWidget(btn_dialog_about)

        btn_dialog_aboutqt = QPushButton('Abrir diálogo do tipo sobre (aboutqt)')
        btn_dialog_aboutqt.clicked.connect(self.open_dialog_aboutqt)
        vbox.addWidget(btn_dialog_aboutqt)

        btn_dialog_critical = QPushButton('Abrir diálogo do tipo crítico (critical)')
        btn_dialog_critical.clicked.connect(self.open_dialog_critical)
        vbox.addWidget(btn_dialog_critical)

        btn_dialog_information = QPushButton('Abrir diálogo do tipo informação (information)')
        btn_dialog_information.clicked.connect(self.open_dialog_information)
        vbox.addWidget(btn_dialog_information)

        btn_dialog_question = QPushButton('Abrir diálogo do tipo questão (question)')
        btn_dialog_question.clicked.connect(self.open_dialog_question)
        vbox.addWidget(btn_dialog_question)

        btn_dialog_warning = QPushButton('Abrir diálogo do tipo alerta (warning)')
        btn_dialog_warning.clicked.connect(self.open_dialog_warning)
        vbox.addWidget(btn_dialog_warning)
示例#32
0
class QPackagePanel(QGroupBox):
    """The package display portion of the ATO panel.

    Displays the package assigned to the player's ATO, and includes edit and
    delete buttons for package management.
    """

    def __init__(self, model: AtoModel) -> None:
        super().__init__("Packages")
        self.ato_model = model
        self.ato_model.layoutChanged.connect(self.on_current_changed)

        self.vbox = QVBoxLayout()
        self.setLayout(self.vbox)

        self.tip = QLabel(
            "To create a new package, right click the mission target on the "
            "map. To target airbase objectives, use\n"
            "the attack button in the airbase view."
        )
        self.vbox.addWidget(self.tip)

        self.package_list = QPackageList(self.ato_model)
        self.vbox.addWidget(self.package_list)

        self.button_row = QHBoxLayout()
        self.vbox.addLayout(self.button_row)

        self.edit_button = QPushButton("Edit")
        self.edit_button.clicked.connect(self.on_edit)
        self.button_row.addWidget(self.edit_button)

        self.delete_button = QPushButton("Delete")
        # noinspection PyTypeChecker
        self.delete_button.setProperty("style", "btn-danger")
        self.delete_button.clicked.connect(self.on_delete)
        self.button_row.addWidget(self.delete_button)

        self.current_changed.connect(self.on_current_changed)
        self.on_current_changed()

    @property
    def current_changed(self):
        """Returns the signal emitted when the flight selection changes."""
        return self.package_list.selectionModel().currentChanged

    def on_current_changed(self) -> None:
        """Updates the status of the edit and delete buttons."""
        index = self.package_list.currentIndex()
        enabled = index.isValid()
        self.edit_button.setEnabled(enabled)
        self.delete_button.setEnabled(enabled)
        self.change_map_package_selection(index)

    def change_map_package_selection(self, index: QModelIndex) -> None:
        if not index.isValid():
            GameUpdateSignal.get_instance().select_package(None)
            return

        package = self.ato_model.get_package_model(index)
        if package.rowCount() == 0:
            GameUpdateSignal.get_instance().select_package(None)
        else:
            GameUpdateSignal.get_instance().select_package(index.row())

    def on_edit(self) -> None:
        """Opens the package edit dialog."""
        index = self.package_list.currentIndex()
        if not index.isValid():
            logging.error(f"Cannot edit package when no package is selected.")
            return
        self.package_list.edit_package(index)

    def on_delete(self) -> None:
        """Removes the package from the ATO."""
        index = self.package_list.currentIndex()
        if not index.isValid():
            logging.error(f"Cannot delete package when no package is selected.")
            return
        self.package_list.delete_package(index)
示例#33
0
class QMissionPlanning(QDialog):
    def __init__(self, game: Game):
        super(QMissionPlanning, self).__init__()
        self.game = game
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setMinimumSize(1000, 440)
        self.setModal(True)
        self.setWindowTitle("Mission Preparation")
        self.setWindowIcon(EVENT_ICONS["strike"])
        self.init_ui()
        print("DONE")

    def init_ui(self):

        self.captured_cp = [
            cp for cp in self.game.theater.controlpoints if cp.captured
        ]

        self.layout = QGridLayout()
        self.left_bar_layout = QVBoxLayout()

        self.select_airbase = QChooseAirbase(self.game)
        self.select_airbase.selected_airbase_changed.connect(
            self.on_departure_cp_changed)
        self.planned_flight_view = QPlannedFlightsView(None)
        self.available_aircraft_at_selected_location = {}
        if self.captured_cp[0].id in self.game.planners.keys():
            self.planner = self.game.planners[self.captured_cp[0].id]
            self.planned_flight_view.set_flight_planner(self.planner)
            self.selected_cp = self.captured_cp[0]
            self.available_aircraft_at_selected_location = self.planner.get_available_aircraft(
            )

        self.planned_flight_view.selectionModel().setCurrentIndex(
            self.planned_flight_view.indexAt(QPoint(1, 1)),
            QItemSelectionModel.Rows)
        self.planned_flight_view.selectionModel().selectionChanged.connect(
            self.on_flight_selection_change)

        if len(self.planned_flight_view.flight_planner.flights) > 0:
            self.flight_planner = QFlightPlanner(
                self.planned_flight_view.flight_planner.flights[0], self.game,
                self.planned_flight_view.flight_planner, 0)
            self.flight_planner.on_planned_flight_changed.connect(
                self.update_planned_flight_view)
        else:
            self.flight_planner = QFlightPlanner(
                None, self.game, self.planned_flight_view.flight_planner, 0)
            self.flight_planner.on_planned_flight_changed.connect(
                self.update_planned_flight_view)

        self.add_flight_button = QPushButton("Add Flight")
        self.add_flight_button.clicked.connect(self.on_add_flight)
        self.delete_flight_button = QPushButton("Delete Selected")
        self.delete_flight_button.setProperty("style", "btn-danger")
        self.delete_flight_button.clicked.connect(self.on_delete_flight)

        self.button_layout = QHBoxLayout()
        self.button_layout.addStretch()
        self.button_layout.addWidget(self.delete_flight_button)
        self.button_layout.addWidget(self.add_flight_button)

        self.mission_start_button = QPushButton("Take Off")
        self.mission_start_button.setProperty("style", "start-button")
        self.mission_start_button.clicked.connect(self.on_start)

        self.left_bar_layout.addWidget(self.select_airbase)
        self.left_bar_layout.addWidget(self.planned_flight_view)
        self.left_bar_layout.addLayout(self.button_layout)

        self.layout.addLayout(self.left_bar_layout, 0, 0)
        self.layout.addWidget(self.flight_planner, 0, 1)
        self.layout.addWidget(self.mission_start_button,
                              1,
                              1,
                              alignment=Qt.AlignRight)

        self.setLayout(self.layout)

    @Slot(str)
    def on_departure_cp_changed(self, cp_name):
        cps = [
            cp for cp in self.game.theater.controlpoints if cp.name == cp_name
        ]

        print(cps)

        if len(cps) == 1:
            self.selected_cp = cps[0]
            self.planner = self.game.planners[cps[0].id]
            self.available_aircraft_at_selected_location = self.planner.get_available_aircraft(
            )
            self.planned_flight_view.set_flight_planner(self.planner)
        else:
            self.available_aircraft_at_selected_location = {}
            self.planned_flight_view.set_flight_planner(None)

    def on_flight_selection_change(self):

        print("On flight selection change")

        index = self.planned_flight_view.selectionModel().currentIndex().row()
        self.planned_flight_view.repaint()

        if self.flight_planner is not None:
            self.flight_planner.on_planned_flight_changed.disconnect()
            self.flight_planner.clearTabs()

        try:
            flight = self.planner.flights[index]
        except IndexError:
            flight = None
        self.flight_planner = QFlightPlanner(
            flight, self.game, self.planner,
            self.flight_planner.currentIndex())
        self.flight_planner.on_planned_flight_changed.connect(
            self.update_planned_flight_view)
        self.layout.addWidget(self.flight_planner, 0, 1)

    def update_planned_flight_view(self):
        self.planned_flight_view.update_content()

    def on_add_flight(self):
        possible_aircraft_type = list(self.selected_cp.base.aircraft.keys())

        if len(possible_aircraft_type) == 0:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Information)
            msg.setText("No more aircraft are available on " +
                        self.selected_cp.name + " airbase.")
            msg.setWindowTitle("No more aircraft")
            msg.setStandardButtons(QMessageBox.Ok)
            msg.setWindowFlags(Qt.WindowStaysOnTopHint)
            msg.exec_()
        else:
            self.subwindow = QFlightCreator(self.game, self.selected_cp,
                                            possible_aircraft_type,
                                            self.planned_flight_view)
            self.subwindow.show()

    def on_delete_flight(self):
        index = self.planned_flight_view.selectionModel().currentIndex().row()
        self.planner.remove_flight(index)
        self.planned_flight_view.set_flight_planner(self.planner, index)

    def on_start(self):

        # TODO : refactor this nonsense
        self.gameEvent = None
        for event in self.game.events:
            if isinstance(event,
                          FrontlineAttackEvent) and event.is_player_attacking:
                self.gameEvent = event
        if self.gameEvent is None:
            self.gameEvent = FrontlineAttackEvent(
                self.game, self.game.theater.controlpoints[0],
                self.game.theater.controlpoints[0],
                self.game.theater.controlpoints[0].position,
                self.game.player_name, self.game.enemy_name)
        #if self.awacs_checkbox.isChecked() == 1:
        #    self.gameEvent.is_awacs_enabled = True
        #    self.game.awacs_expense_commit()
        #else:
        #    self.gameEvent.is_awacs_enabled = False
        self.gameEvent.is_awacs_enabled = True
        self.gameEvent.ca_slots = 1
        self.gameEvent.departure_cp = self.game.theater.controlpoints[0]
        self.gameEvent.player_attacking({CAS: {}, CAP: {}})
        self.gameEvent.depart_from = self.game.theater.controlpoints[0]

        self.game.initiate_event(self.gameEvent)
        waiting = QWaitingForMissionResultWindow(self.gameEvent, self.game)
        waiting.show()
        self.close()
示例#34
0
class QFlightPanel(QGroupBox):
    """The flight display portion of the ATO panel.

    Displays the flights assigned to the selected package, and includes edit and
    delete buttons for flight management.
    """

    def __init__(
        self, game_model: GameModel, package_model: Optional[PackageModel] = None
    ) -> None:
        super().__init__("Flights")
        self.game_model = game_model
        self.package_model = package_model

        self.vbox = QVBoxLayout()
        self.setLayout(self.vbox)

        self.tip = QLabel(
            "To add flights to a package, edit the package by double clicking "
            "it or pressing the edit button."
        )
        self.vbox.addWidget(self.tip)

        self.flight_list = QFlightList(game_model, package_model)
        self.vbox.addWidget(self.flight_list)

        self.button_row = QHBoxLayout()
        self.vbox.addLayout(self.button_row)

        self.edit_button = QPushButton("Edit")
        self.edit_button.clicked.connect(self.on_edit)
        self.button_row.addWidget(self.edit_button)

        self.delete_button = QPushButton("Delete")
        # noinspection PyTypeChecker
        self.delete_button.setProperty("style", "btn-danger")
        self.delete_button.clicked.connect(self.on_delete)
        self.button_row.addWidget(self.delete_button)

        self.selection_changed.connect(self.on_selection_changed)
        self.on_selection_changed()

    def set_package(self, model: Optional[PackageModel]) -> None:
        """Sets the package model to display."""
        self.package_model = model
        self.flight_list.set_package(model)
        self.selection_changed.connect(self.on_selection_changed)
        self.on_selection_changed()

    @property
    def selection_changed(self):
        """Returns the signal emitted when the flight selection changes."""
        return self.flight_list.selectionModel().selectionChanged

    def on_selection_changed(self) -> None:
        """Updates the status of the edit and delete buttons."""
        index = self.flight_list.currentIndex()
        enabled = index.isValid()
        self.edit_button.setEnabled(enabled)
        self.delete_button.setEnabled(enabled)
        self.change_map_flight_selection(index)

    @staticmethod
    def change_map_flight_selection(index: QModelIndex) -> None:
        if not index.isValid():
            GameUpdateSignal.get_instance().select_flight(None)
            return

        GameUpdateSignal.get_instance().select_flight(index.row())

    def on_edit(self) -> None:
        """Opens the flight edit dialog."""
        index = self.flight_list.currentIndex()
        if not index.isValid():
            logging.error(f"Cannot edit flight when no flight is selected.")
            return
        self.flight_list.edit_flight(index)

    def on_delete(self) -> None:
        """Removes the selected flight from the package."""
        index = self.flight_list.currentIndex()
        if not index.isValid():
            logging.error(f"Cannot delete flight when no flight is selected.")
            return
        self.flight_list.delete_flight(index)
示例#35
0
    def __init__(self, mainWindow, parent=None):
        super(Toolbar, self).__init__(parent)

        self.__mainWindow = mainWindow

        #buttons
        self.generateButton = ToolButton("BalanceVerification.xpm",
                                         "Generate balance verification", self)
        self.sortButton = ToolButton("SortBy.xpm", "Sort table", self)
        self.sortMenu = QMenu()
        self.sortMenu.addAction(
            "Name", lambda: self.__mainWindow.contentTab.sortTable("name"))
        self.sortMenu.addAction(
            "Firstname",
            lambda: self.__mainWindow.contentTab.sortTable("firstName"))
        self.sortMenu.addAction(
            "Surname",
            lambda: self.__mainWindow.contentTab.sortTable("surname"))
        self.sortMenu.addAction(
            "eMail", lambda: self.__mainWindow.contentTab.sortTable("eMail"))
        self.sortMenu.addAction(
            "cotisation",
            lambda: self.__mainWindow.contentTab.sortTable("cotisation"))
        self.sortMenu.addAction(
            "Groups",
            lambda: self.__mainWindow.contentTab.sortTable("belongingGroups"))
        self.sortButton.setMenu(self.sortMenu)
        self.sortButton_inv = ToolButton("SortBy_inv.xpm", "Sort table", self)
        self.sortMenu_inv = QMenu()
        self.sortMenu_inv.addAction(
            "Name",
            lambda: self.__mainWindow.contentTab.sortTable("name", True))
        self.sortMenu_inv.addAction(
            "Firstname",
            lambda: self.__mainWindow.contentTab.sortTable("firstName", True))
        self.sortMenu_inv.addAction(
            "Surname",
            lambda: self.__mainWindow.contentTab.sortTable("surname", True))
        self.sortMenu_inv.addAction(
            "eMail",
            lambda: self.__mainWindow.contentTab.sortTable("eMail", True))
        self.sortMenu_inv.addAction(
            "cotisation",
            lambda: self.__mainWindow.contentTab.sortTable("cotisation", True))
        self.sortMenu_inv.addAction(
            "Groups", lambda: self.__mainWindow.contentTab.sortTable(
                "belongingGroups", True))
        self.sortButton_inv.setMenu(self.sortMenu_inv)
        self.addButton = ToolButton("Add.xpm", "Add an element", self)
        self.addButton.released.connect(self.addItem)
        self.substractButton = ToolButton("Substract.xpm",
                                          "Substract selected element", self)
        self.substractButton.released.connect(self.delItem)
        #layout
        layout = QVBoxLayout(self)
        layout.addWidget(self.sortButton)
        layout.addWidget(self.sortButton_inv)
        layout.addWidget(self.addButton)
        layout.addWidget(self.substractButton)
        layout.addWidget(self.generateButton)
        layout.addStretch()
        self.setLayout(layout)
示例#36
0
    def __init__(self):
        super(MyWidget, self).__init__(None)

        self.view = View()
        self.grid = DateTimeGrid()
        self.slider = QSlider()
        self.model = QStandardItemModel()
        self.cmodel = ConstraintModel()

        for h in range(0, 19):
            topitem = MyStandardItem("Top Item " + str(h))
            for i in range(0, 19):
                item = MyStandardItem("Multi Item " + str(i))
                for j in range(0, 29, 3):
                    item.appendRow([
                        MyStandardItem("Item " + str(j)),
                        MyStandardItem(KDGantt.TypeTask),
                        MyStandardItem(QDateTime.currentDateTime().addDays(j),
                                       KDGantt.StartTimeRole),
                        MyStandardItem(
                            QDateTime.currentDateTime().addDays(j + 1 + i / 7),
                            KDGantt.EndTimeRole),
                        MyStandardItem(50)
                    ])

                item.appendRow([
                    MyStandardItem("Event"),
                    MyStandardItem(KDGantt.TypeEvent),
                    MyStandardItem(QDateTime.currentDateTime(),
                                   KDGantt.StartTimeRole),
                    MyStandardItem(QDateTime(), KDGantt.EndTimeRole),
                    MyStandardItem("")
                ])

                topitem.appendRow([
                    item,
                    MyStandardItem(KDGantt.TypeMulti),
                    MyStandardItem(""),
                    MyStandardItem(""),
                    MyStandardItem("")
                ])

            self.model.appendRow([
                topitem,
                MyStandardItem(KDGantt.TypeMulti),
                MyStandardItem(""),
                MyStandardItem(""),
                MyStandardItem("")
            ])

        self.model.appendRow([MyStandardItem("No data")])

        ##cmodel.addConstraint( KDGantt::Constraint( proxyModel.index( 0, 3 ), proxyModel.index( 10, 3 ) ) );
        ##cmodel.addConstraint( KDGantt::Constraint( proxyModel.index( 10, 3 ), proxyModel.index( 5, 3 ) ) );
        pidx = self.model.index(0, 0)
        pidx = self.model.index(0, 0, pidx)
        self.cmodel.addConstraint(
            Constraint(self.model.index(0, 0, pidx),
                       self.model.index(1, 0, pidx)))
        self.cmodel.addConstraint(
            Constraint(self.model.index(1, 0, pidx),
                       self.model.index(0, 0, pidx)))
        self.cmodel.addConstraint(
            Constraint(self.model.index(1, 0, pidx),
                       self.model.index(10, 0, pidx)))
        self.cmodel.addConstraint(
            Constraint(self.model.index(3, 0, pidx),
                       self.model.index(5, 0, pidx)))
        self.cmodel.addConstraint(
            Constraint(self.model.index(7, 0, pidx),
                       self.model.index(4, 0, pidx)))

        self.slider.setOrientation(Qt.Horizontal)
        self.slider.setRange(1, 10000)
        self.slider.setValue(100)
        l = QVBoxLayout(self)
        l.addWidget(self.view)
        l.addWidget(self.slider)
        self.grid.setStartDateTime(QDateTime.currentDateTime().addDays(-3))
        self.grid.setDayWidth(100)
        ##grid.setNoInformationBrush( Qt::NoBrush );
        self.view.setGrid(self.grid)
        self.view.setModel(self.model)
        ##view.setConstraintModel( &cmodel );
        self.slider.valueChanged.connect(self.slotZoom)

        pb1 = QPushButton("Print Preview...", self)
        pb2 = QPushButton("Print...", self)

        l.addWidget(pb1)
        l.addWidget(pb2)

        pb1.clicked.connect(self.slotPrintPreview)
        pb2.clicked.connect(self.slotPrint)

        gv = self.view.graphicsView()
        gv.setHeaderContextMenuPolicy(Qt.CustomContextMenu)
        gv.headerContextMenuRequested.connect(self.slotHeaderMenu)
示例#37
0
    def __init__(self, image, parent=None):
        super(CloningWidget, self).__init__(parent)

        self.detector_combo = QComboBox()
        self.detector_combo.addItems(
            [self.tr('BRISK'),
             self.tr('ORB'),
             self.tr('AKAZE')])
        self.detector_combo.setCurrentIndex(0)
        self.detector_combo.setToolTip(
            self.tr('Algorithm used for localization and description'))
        self.response_spin = QSpinBox()
        self.response_spin.setRange(0, 100)
        self.response_spin.setSuffix(self.tr('%'))
        self.response_spin.setValue(90)
        self.response_spin.setToolTip(
            self.tr('Maximum keypoint response to perform matching'))
        self.matching_spin = QSpinBox()
        self.matching_spin.setRange(1, 100)
        self.matching_spin.setSuffix(self.tr('%'))
        self.matching_spin.setValue(20)
        self.matching_spin.setToolTip(
            self.tr('Maximum metric difference to accept matching'))
        self.distance_spin = QSpinBox()
        self.distance_spin.setRange(1, 100)
        self.distance_spin.setSuffix(self.tr('%'))
        self.distance_spin.setValue(15)
        self.distance_spin.setToolTip(
            self.tr('Maximum distance between matches in the same cluster'))
        self.cluster_spin = QSpinBox()
        self.cluster_spin.setRange(1, 20)
        self.cluster_spin.setValue(5)
        self.cluster_spin.setToolTip(
            self.tr('Minimum number of keypoints to create a new cluster'))
        self.nolines_check = QCheckBox(self.tr('Hide lines'))
        self.nolines_check.setToolTip(self.tr('Disable match line drawing'))
        self.process_button = QPushButton(self.tr('Process'))
        self.process_button.setToolTip(self.tr('Perform automatic detection'))
        self.status_label = QLabel(
            self.tr('[Press "Process" button to search for cloned regions]'))

        self.image = image
        self.viewer = ImageViewer(self.image, self.image)
        self.gray = cv.cvtColor(self.image, cv.COLOR_BGR2GRAY)
        self.keypoints = self.kpts = self.desc = self.matches = self.clusters = None
        self.canceled = False

        self.detector_combo.currentIndexChanged.connect(self.update_detector)
        self.response_spin.valueChanged.connect(self.update_detector)
        self.matching_spin.valueChanged.connect(self.update_matching)
        self.distance_spin.valueChanged.connect(self.update_cluster)
        self.cluster_spin.valueChanged.connect(self.update_cluster)
        self.nolines_check.stateChanged.connect(self.process)
        self.process_button.clicked.connect(self.process)

        top_layout = QHBoxLayout()
        top_layout.addWidget(QLabel(self.tr('Detector:')))
        top_layout.addWidget(self.detector_combo)
        top_layout.addWidget(QLabel(self.tr('Response:')))
        top_layout.addWidget(self.response_spin)
        top_layout.addWidget(QLabel(self.tr('Matching:')))
        top_layout.addWidget(self.matching_spin)
        top_layout.addWidget(QLabel(self.tr('Distance:')))
        top_layout.addWidget(self.distance_spin)
        top_layout.addWidget(QLabel(self.tr('Cluster:')))
        top_layout.addWidget(self.cluster_spin)
        top_layout.addWidget(self.nolines_check)
        top_layout.addWidget(self.process_button)
        top_layout.addStretch()

        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addWidget(self.status_label)
        main_layout.addWidget(self.viewer)
        self.setLayout(main_layout)
示例#38
0
class QSettingsWindow(QDialog):
    def __init__(self, game: Game):
        super(QSettingsWindow, self).__init__()

        self.game = game
        self.pluginsPage = None
        self.pluginsOptionsPage = None
        self.campaign_management_page = QWidget()

        self.setModal(True)
        self.setWindowTitle("Settings")
        self.setWindowIcon(CONST.ICONS["Settings"])
        self.setMinimumSize(600, 250)

        self.initUi()

    def initUi(self):
        self.layout = QGridLayout()

        self.categoryList = QListView()
        self.right_layout = QStackedLayout()

        self.categoryList.setMaximumWidth(175)

        self.categoryModel = QStandardItemModel(self.categoryList)

        self.categoryList.setIconSize(QSize(32, 32))

        self.initDifficultyLayout()
        difficulty = QStandardItem("Difficulty")
        difficulty.setIcon(CONST.ICONS["Missile"])
        difficulty.setEditable(False)
        difficulty.setSelectable(True)
        self.categoryModel.appendRow(difficulty)
        self.right_layout.addWidget(self.difficultyPage)

        self.init_campaign_management_layout()
        campaign_management = QStandardItem("Campaign Management")
        campaign_management.setIcon(CONST.ICONS["Money"])
        campaign_management.setEditable(False)
        campaign_management.setSelectable(True)
        self.categoryModel.appendRow(campaign_management)
        self.right_layout.addWidget(self.campaign_management_page)

        self.initGeneratorLayout()
        generator = QStandardItem("Mission Generator")
        generator.setIcon(CONST.ICONS["Generator"])
        generator.setEditable(False)
        generator.setSelectable(True)
        self.categoryModel.appendRow(generator)
        self.right_layout.addWidget(self.generatorPage)

        self.initCheatLayout()
        cheat = QStandardItem("Cheat Menu")
        cheat.setIcon(CONST.ICONS["Cheat"])
        cheat.setEditable(False)
        cheat.setSelectable(True)
        self.categoryModel.appendRow(cheat)
        self.right_layout.addWidget(self.cheatPage)

        self.pluginsPage = PluginsPage()
        plugins = QStandardItem("LUA Plugins")
        plugins.setIcon(CONST.ICONS["Plugins"])
        plugins.setEditable(False)
        plugins.setSelectable(True)
        self.categoryModel.appendRow(plugins)
        self.right_layout.addWidget(self.pluginsPage)

        self.pluginsOptionsPage = PluginOptionsPage()
        pluginsOptions = QStandardItem("LUA Plugins Options")
        pluginsOptions.setIcon(CONST.ICONS["PluginsOptions"])
        pluginsOptions.setEditable(False)
        pluginsOptions.setSelectable(True)
        self.categoryModel.appendRow(pluginsOptions)
        self.right_layout.addWidget(self.pluginsOptionsPage)

        self.categoryList.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.categoryList.setModel(self.categoryModel)
        self.categoryList.selectionModel().setCurrentIndex(
            self.categoryList.indexAt(QPoint(1, 1)),
            QItemSelectionModel.Select)
        self.categoryList.selectionModel().selectionChanged.connect(
            self.onSelectionChanged)

        self.layout.addWidget(self.categoryList, 0, 0, 1, 1)
        self.layout.addLayout(self.right_layout, 0, 1, 5, 1)

        self.setLayout(self.layout)

    def init(self):
        pass

    def initDifficultyLayout(self):

        self.difficultyPage = QWidget()
        self.difficultyLayout = QVBoxLayout()
        self.difficultyLayout.setAlignment(Qt.AlignTop)
        self.difficultyPage.setLayout(self.difficultyLayout)

        # DCS AI difficulty settings
        self.aiDifficultySettings = QGroupBox("AI Difficulty")
        self.aiDifficultyLayout = QGridLayout()
        self.playerCoalitionSkill = QComboBox()
        self.enemyCoalitionSkill = QComboBox()
        self.enemyAASkill = QComboBox()
        for skill in CONST.SKILL_OPTIONS:
            self.playerCoalitionSkill.addItem(skill)
            self.enemyCoalitionSkill.addItem(skill)
            self.enemyAASkill.addItem(skill)

        self.playerCoalitionSkill.setCurrentIndex(
            CONST.SKILL_OPTIONS.index(self.game.settings.player_skill))
        self.enemyCoalitionSkill.setCurrentIndex(
            CONST.SKILL_OPTIONS.index(self.game.settings.enemy_skill))
        self.enemyAASkill.setCurrentIndex(
            CONST.SKILL_OPTIONS.index(self.game.settings.enemy_vehicle_skill))

        self.player_income = TenthsSpinSlider(
            "Player income multiplier",
            1,
            50,
            int(self.game.settings.player_income_multiplier * 10),
        )
        self.player_income.spinner.valueChanged.connect(self.applySettings)
        self.enemy_income = TenthsSpinSlider(
            "Enemy income multiplier",
            1,
            50,
            int(self.game.settings.enemy_income_multiplier * 10),
        )
        self.enemy_income.spinner.valueChanged.connect(self.applySettings)

        self.playerCoalitionSkill.currentIndexChanged.connect(
            self.applySettings)
        self.enemyCoalitionSkill.currentIndexChanged.connect(
            self.applySettings)
        self.enemyAASkill.currentIndexChanged.connect(self.applySettings)

        # Mission generation settings related to difficulty
        self.missionSettings = QGroupBox("Mission Difficulty")
        self.missionLayout = QGridLayout()

        self.manpads = QCheckBox()
        self.manpads.setChecked(self.game.settings.manpads)
        self.manpads.toggled.connect(self.applySettings)

        self.noNightMission = QCheckBox()
        self.noNightMission.setChecked(self.game.settings.night_disabled)
        self.noNightMission.toggled.connect(self.applySettings)

        # DCS Mission options
        self.missionRestrictionsSettings = QGroupBox("Mission Restrictions")
        self.missionRestrictionsLayout = QGridLayout()

        self.difficultyLabel = QComboBox()
        [self.difficultyLabel.addItem(t) for t in CONST.LABELS_OPTIONS]
        self.difficultyLabel.setCurrentIndex(
            CONST.LABELS_OPTIONS.index(self.game.settings.labels))
        self.difficultyLabel.currentIndexChanged.connect(self.applySettings)

        self.mapVisibiitySelection = QComboBox()
        self.mapVisibiitySelection.addItem("All", ForcedOptions.Views.All)
        if self.game.settings.map_coalition_visibility == ForcedOptions.Views.All:
            self.mapVisibiitySelection.setCurrentIndex(0)
        self.mapVisibiitySelection.addItem("Fog of War",
                                           ForcedOptions.Views.Allies)
        if self.game.settings.map_coalition_visibility == ForcedOptions.Views.Allies:
            self.mapVisibiitySelection.setCurrentIndex(1)
        self.mapVisibiitySelection.addItem("Allies Only",
                                           ForcedOptions.Views.OnlyAllies)
        if (self.game.settings.map_coalition_visibility ==
                ForcedOptions.Views.OnlyAllies):
            self.mapVisibiitySelection.setCurrentIndex(2)
        self.mapVisibiitySelection.addItem("Own Aircraft Only",
                                           ForcedOptions.Views.MyAircraft)
        if (self.game.settings.map_coalition_visibility ==
                ForcedOptions.Views.MyAircraft):
            self.mapVisibiitySelection.setCurrentIndex(3)
        self.mapVisibiitySelection.addItem("Map Only",
                                           ForcedOptions.Views.OnlyMap)
        if self.game.settings.map_coalition_visibility == ForcedOptions.Views.OnlyMap:
            self.mapVisibiitySelection.setCurrentIndex(4)
        self.mapVisibiitySelection.currentIndexChanged.connect(
            self.applySettings)

        self.ext_views = QCheckBox()
        self.ext_views.setChecked(self.game.settings.external_views_allowed)
        self.ext_views.toggled.connect(self.applySettings)

        self.aiDifficultyLayout.addWidget(QLabel("Player coalition skill"), 0,
                                          0)
        self.aiDifficultyLayout.addWidget(self.playerCoalitionSkill, 0, 1,
                                          Qt.AlignRight)
        self.aiDifficultyLayout.addWidget(QLabel("Enemy coalition skill"), 1,
                                          0)
        self.aiDifficultyLayout.addWidget(self.enemyCoalitionSkill, 1, 1,
                                          Qt.AlignRight)
        self.aiDifficultyLayout.addWidget(
            QLabel("Enemy AA and vehicles skill"), 2, 0)
        self.aiDifficultyLayout.addWidget(self.enemyAASkill, 2, 1,
                                          Qt.AlignRight)
        self.aiDifficultyLayout.addLayout(self.player_income, 3, 0)
        self.aiDifficultyLayout.addLayout(self.enemy_income, 4, 0)
        self.aiDifficultySettings.setLayout(self.aiDifficultyLayout)
        self.difficultyLayout.addWidget(self.aiDifficultySettings)

        self.missionLayout.addWidget(QLabel("Manpads on frontlines"), 0, 0)
        self.missionLayout.addWidget(self.manpads, 0, 1, Qt.AlignRight)
        self.missionLayout.addWidget(QLabel("No night missions"), 1, 0)
        self.missionLayout.addWidget(self.noNightMission, 1, 1, Qt.AlignRight)
        self.missionSettings.setLayout(self.missionLayout)
        self.difficultyLayout.addWidget(self.missionSettings)

        self.missionRestrictionsLayout.addWidget(QLabel("In Game Labels"), 0,
                                                 0)
        self.missionRestrictionsLayout.addWidget(self.difficultyLabel, 0, 1,
                                                 Qt.AlignRight)
        self.missionRestrictionsLayout.addWidget(
            QLabel("Map visibility options"), 1, 0)
        self.missionRestrictionsLayout.addWidget(self.mapVisibiitySelection, 1,
                                                 1, Qt.AlignRight)
        self.missionRestrictionsLayout.addWidget(
            QLabel("Allow external views"), 2, 0)
        self.missionRestrictionsLayout.addWidget(self.ext_views, 2, 1,
                                                 Qt.AlignRight)
        self.missionRestrictionsSettings.setLayout(
            self.missionRestrictionsLayout)
        self.difficultyLayout.addWidget(self.missionRestrictionsSettings)

    def init_campaign_management_layout(self) -> None:
        campaign_layout = QVBoxLayout()
        campaign_layout.setAlignment(Qt.AlignTop)
        self.campaign_management_page.setLayout(campaign_layout)

        general = QGroupBox("General")
        campaign_layout.addWidget(general)

        general_layout = QGridLayout()
        general.setLayout(general_layout)

        def set_restict_weapons_by_date(value: bool) -> None:
            self.game.settings.restrict_weapons_by_date = value

        restrict_weapons = QCheckBox()
        restrict_weapons.setChecked(
            self.game.settings.restrict_weapons_by_date)
        restrict_weapons.toggled.connect(set_restict_weapons_by_date)

        tooltip_text = (
            "Restricts weapon availability based on the campaign date. Data is "
            "extremely incomplete so does not affect all weapons.")
        restrict_weapons.setToolTip(tooltip_text)
        restrict_weapons_label = QLabel("Restrict weapons by date (WIP)")
        restrict_weapons_label.setToolTip(tooltip_text)

        general_layout.addWidget(restrict_weapons_label, 0, 0)
        general_layout.addWidget(restrict_weapons, 0, 1, Qt.AlignRight)

        automation = QGroupBox("HQ Automation")
        campaign_layout.addWidget(automation)

        automation_layout = QGridLayout()
        automation.setLayout(automation_layout)

        def set_runway_automation(value: bool) -> None:
            self.game.settings.automate_runway_repair = value

        def set_front_line_automation(value: bool) -> None:
            self.game.settings.automate_front_line_reinforcements = value

        def set_aircraft_automation(value: bool) -> None:
            self.game.settings.automate_aircraft_reinforcements = value

        runway_repair = QCheckBox()
        runway_repair.setChecked(self.game.settings.automate_runway_repair)
        runway_repair.toggled.connect(set_runway_automation)

        automation_layout.addWidget(QLabel("Automate runway repairs"), 0, 0)
        automation_layout.addWidget(runway_repair, 0, 1, Qt.AlignRight)

        front_line = QCheckBox()
        front_line.setChecked(
            self.game.settings.automate_front_line_reinforcements)
        front_line.toggled.connect(set_front_line_automation)

        automation_layout.addWidget(QLabel("Automate front-line purchases"), 1,
                                    0)
        automation_layout.addWidget(front_line, 1, 1, Qt.AlignRight)

        aircraft = QCheckBox()
        aircraft.setChecked(
            self.game.settings.automate_aircraft_reinforcements)
        aircraft.toggled.connect(set_aircraft_automation)

        automation_layout.addWidget(QLabel("Automate aircraft purchases"), 2,
                                    0)
        automation_layout.addWidget(aircraft, 2, 1, Qt.AlignRight)

    def initGeneratorLayout(self):
        self.generatorPage = QWidget()
        self.generatorLayout = QVBoxLayout()
        self.generatorLayout.setAlignment(Qt.AlignTop)
        self.generatorPage.setLayout(self.generatorLayout)

        self.gameplay = QGroupBox("Gameplay")
        self.gameplayLayout = QGridLayout()
        self.gameplayLayout.setAlignment(Qt.AlignTop)
        self.gameplay.setLayout(self.gameplayLayout)

        self.supercarrier = QCheckBox()
        self.supercarrier.setChecked(self.game.settings.supercarrier)
        self.supercarrier.toggled.connect(self.applySettings)

        self.generate_marks = QCheckBox()
        self.generate_marks.setChecked(self.game.settings.generate_marks)
        self.generate_marks.toggled.connect(self.applySettings)

        self.never_delay_players = QCheckBox()
        self.never_delay_players.setChecked(
            self.game.settings.never_delay_player_flights)
        self.never_delay_players.toggled.connect(self.applySettings)
        self.never_delay_players.setToolTip(
            "When checked, player flights with a delayed start time will be "
            "spawned immediately. AI wingmen may begin startup immediately.")

        self.gameplayLayout.addWidget(QLabel("Use Supercarrier Module"), 0, 0)
        self.gameplayLayout.addWidget(self.supercarrier, 0, 1, Qt.AlignRight)
        self.gameplayLayout.addWidget(QLabel("Put Objective Markers on Map"),
                                      1, 0)
        self.gameplayLayout.addWidget(self.generate_marks, 1, 1, Qt.AlignRight)
        self.gameplayLayout.addWidget(QLabel("Never delay player flights"), 2,
                                      0)
        self.gameplayLayout.addWidget(self.never_delay_players, 2, 1,
                                      Qt.AlignRight)

        start_type_label = QLabel(
            "Default start type for AI aircraft:<br /><strong>Warning: " +
            "Any option other than Cold breaks OCA/Aircraft missions.</strong>"
        )
        start_type_label.setToolTip(START_TYPE_TOOLTIP)
        start_type = StartTypeComboBox(self.game.settings)
        start_type.setCurrentText(self.game.settings.default_start_type)

        self.gameplayLayout.addWidget(start_type_label, 3, 0)
        self.gameplayLayout.addWidget(start_type, 3, 1)

        self.performance = QGroupBox("Performance")
        self.performanceLayout = QGridLayout()
        self.performanceLayout.setAlignment(Qt.AlignTop)
        self.performance.setLayout(self.performanceLayout)

        self.smoke = QCheckBox()
        self.smoke.setChecked(self.game.settings.perf_smoke_gen)
        self.smoke.toggled.connect(self.applySettings)

        self.red_alert = QCheckBox()
        self.red_alert.setChecked(self.game.settings.perf_red_alert_state)
        self.red_alert.toggled.connect(self.applySettings)

        self.arti = QCheckBox()
        self.arti.setChecked(self.game.settings.perf_artillery)
        self.arti.toggled.connect(self.applySettings)

        self.moving_units = QCheckBox()
        self.moving_units.setChecked(self.game.settings.perf_moving_units)
        self.moving_units.toggled.connect(self.applySettings)

        self.infantry = QCheckBox()
        self.infantry.setChecked(self.game.settings.perf_infantry)
        self.infantry.toggled.connect(self.applySettings)

        self.destroyed_units = QCheckBox()
        self.destroyed_units.setChecked(
            self.game.settings.perf_destroyed_units)
        self.destroyed_units.toggled.connect(self.applySettings)

        self.culling = QCheckBox()
        self.culling.setChecked(self.game.settings.perf_culling)
        self.culling.toggled.connect(self.applySettings)

        self.culling_distance = QSpinBox()
        self.culling_distance.setMinimum(10)
        self.culling_distance.setMaximum(10000)
        self.culling_distance.setValue(
            self.game.settings.perf_culling_distance)
        self.culling_distance.valueChanged.connect(self.applySettings)

        self.culling_do_not_cull_carrier = QCheckBox()
        self.culling_do_not_cull_carrier.setChecked(
            self.game.settings.perf_do_not_cull_carrier)
        self.culling_do_not_cull_carrier.toggled.connect(self.applySettings)

        self.performanceLayout.addWidget(
            QLabel("Smoke visual effect on frontline"), 0, 0)
        self.performanceLayout.addWidget(self.smoke,
                                         0,
                                         1,
                                         alignment=Qt.AlignRight)
        self.performanceLayout.addWidget(
            QLabel("SAM starts in RED alert mode"), 1, 0)
        self.performanceLayout.addWidget(self.red_alert,
                                         1,
                                         1,
                                         alignment=Qt.AlignRight)
        self.performanceLayout.addWidget(QLabel("Artillery strikes"), 2, 0)
        self.performanceLayout.addWidget(self.arti,
                                         2,
                                         1,
                                         alignment=Qt.AlignRight)
        self.performanceLayout.addWidget(QLabel("Moving ground units"), 3, 0)
        self.performanceLayout.addWidget(self.moving_units,
                                         3,
                                         1,
                                         alignment=Qt.AlignRight)
        self.performanceLayout.addWidget(
            QLabel("Generate infantry squads along vehicles"), 4, 0)
        self.performanceLayout.addWidget(self.infantry,
                                         4,
                                         1,
                                         alignment=Qt.AlignRight)
        self.performanceLayout.addWidget(
            QLabel("Include destroyed units carcass"), 6, 0)
        self.performanceLayout.addWidget(self.destroyed_units,
                                         6,
                                         1,
                                         alignment=Qt.AlignRight)

        self.performanceLayout.addWidget(QHorizontalSeparationLine(), 7, 0, 1,
                                         2)
        self.performanceLayout.addWidget(
            QLabel("Culling of distant units enabled"), 8, 0)
        self.performanceLayout.addWidget(self.culling,
                                         8,
                                         1,
                                         alignment=Qt.AlignRight)
        self.performanceLayout.addWidget(QLabel("Culling distance (km)"), 9, 0)
        self.performanceLayout.addWidget(self.culling_distance,
                                         9,
                                         1,
                                         alignment=Qt.AlignRight)
        self.performanceLayout.addWidget(
            QLabel("Do not cull carrier's surroundings"), 10, 0)
        self.performanceLayout.addWidget(self.culling_do_not_cull_carrier,
                                         10,
                                         1,
                                         alignment=Qt.AlignRight)

        self.generatorLayout.addWidget(self.gameplay)
        self.generatorLayout.addWidget(
            QLabel(
                "Disabling settings below may improve performance, but will impact the overall quality of the experience."
            ))
        self.generatorLayout.addWidget(self.performance)

    def initCheatLayout(self):

        self.cheatPage = QWidget()
        self.cheatLayout = QVBoxLayout()
        self.cheatPage.setLayout(self.cheatLayout)

        self.cheat_options = CheatSettingsBox(self.game, self.applySettings)
        self.cheatLayout.addWidget(self.cheat_options)

        self.moneyCheatBox = QGroupBox("Money Cheat")
        self.moneyCheatBox.setAlignment(Qt.AlignTop)
        self.moneyCheatBoxLayout = QGridLayout()
        self.moneyCheatBox.setLayout(self.moneyCheatBoxLayout)

        cheats_amounts = [25, 50, 100, 200, 500, 1000, -25, -50, -100, -200]
        for i, amount in enumerate(cheats_amounts):
            if amount > 0:
                btn = QPushButton("Cheat +" + str(amount) + "M")
                btn.setProperty("style", "btn-success")
            else:
                btn = QPushButton("Cheat " + str(amount) + "M")
                btn.setProperty("style", "btn-danger")
            btn.clicked.connect(self.cheatLambda(amount))
            self.moneyCheatBoxLayout.addWidget(btn, i / 2, i % 2)
        self.cheatLayout.addWidget(self.moneyCheatBox, stretch=1)

    def cheatLambda(self, amount):
        return lambda: self.cheatMoney(amount)

    def cheatMoney(self, amount):
        logging.info("CHEATING FOR AMOUNT : " + str(amount) + "M")
        self.game.budget += amount
        if amount > 0:
            self.game.informations.append(
                Information(
                    "CHEATER",
                    "You are a cheater and you should feel bad",
                    self.game.turn,
                ))
        else:
            self.game.informations.append(
                Information("CHEATER", "You are still a cheater !",
                            self.game.turn))
        GameUpdateSignal.get_instance().updateGame(self.game)

    def applySettings(self):
        self.game.settings.player_skill = CONST.SKILL_OPTIONS[
            self.playerCoalitionSkill.currentIndex()]
        self.game.settings.enemy_skill = CONST.SKILL_OPTIONS[
            self.enemyCoalitionSkill.currentIndex()]
        self.game.settings.enemy_vehicle_skill = CONST.SKILL_OPTIONS[
            self.enemyAASkill.currentIndex()]
        self.game.settings.player_income_multiplier = self.player_income.value
        self.game.settings.enemy_income_multiplier = self.enemy_income.value
        self.game.settings.manpads = self.manpads.isChecked()
        self.game.settings.labels = CONST.LABELS_OPTIONS[
            self.difficultyLabel.currentIndex()]
        self.game.settings.night_disabled = self.noNightMission.isChecked()
        self.game.settings.map_coalition_visibility = (
            self.mapVisibiitySelection.currentData())
        self.game.settings.external_views_allowed = self.ext_views.isChecked()
        self.game.settings.generate_marks = self.generate_marks.isChecked()
        self.game.settings.never_delay_player_flights = (
            self.never_delay_players.isChecked())

        self.game.settings.supercarrier = self.supercarrier.isChecked()

        self.game.settings.perf_red_alert_state = self.red_alert.isChecked()
        self.game.settings.perf_smoke_gen = self.smoke.isChecked()
        self.game.settings.perf_artillery = self.arti.isChecked()
        self.game.settings.perf_moving_units = self.moving_units.isChecked()
        self.game.settings.perf_infantry = self.infantry.isChecked()
        self.game.settings.perf_destroyed_units = self.destroyed_units.isChecked(
        )

        self.game.settings.perf_culling = self.culling.isChecked()
        self.game.settings.perf_culling_distance = int(
            self.culling_distance.value())
        self.game.settings.perf_do_not_cull_carrier = (
            self.culling_do_not_cull_carrier.isChecked())

        self.game.settings.show_red_ato = self.cheat_options.show_red_ato
        self.game.settings.enable_frontline_cheats = (
            self.cheat_options.show_frontline_cheat)
        self.game.settings.enable_base_capture_cheat = (
            self.cheat_options.show_base_capture_cheat)

        self.game.compute_conflicts_position()
        GameUpdateSignal.get_instance().updateGame(self.game)

    def onSelectionChanged(self):
        index = self.categoryList.selectionModel().currentIndex().row()
        self.right_layout.setCurrentIndex(index)
示例#39
0
class MainWidget(QtWidgets.QWidget):
    data_directory_group_box: DataDirectoryBox
    error_message: QErrorMessage
    grid: QVBoxLayout
    mainnet_group_box: NetworkWidget
    network_grid: Tabs
    testnet_group_box: NetworkWidget

    def __init__(self):
        super().__init__()
        self.setWindowTitle('Node Launcher')
        self.message_box = QMessageBox(self)
        self.error_message = QErrorMessage(self)
        self.message_box.setTextFormat(Qt.RichText)
        try:
            self.testnet_group_box = NetworkWidget(network=TESTNET)
            self.mainnet_group_box = NetworkWidget(network=MAINNET)
        except ZmqPortsNotOpenError as e:
            self.error_message.showMessage(str(e))
            self.error_message.exec_()
            sys.exit(0)

        self.data_directory_group_box = DataDirectoryBox()
        self.data_directory_group_box.file_dialog.new_data_directory.connect(
            self.change_datadir)
        self.data_directory_group_box.set_datadir(
            self.mainnet_group_box.node_set.bitcoin.file['datadir'],
            self.mainnet_group_box.node_set.bitcoin.file['prune'])

        self.network_grid = Tabs(self,
                                 mainnet=self.mainnet_group_box,
                                 testnet=self.testnet_group_box)

        self.grid = QVBoxLayout()
        self.grid.addStretch()
        self.grid.addWidget(self.data_directory_group_box)
        self.grid.addWidget(self.network_grid)
        self.grid.setAlignment(self.data_directory_group_box, Qt.AlignHCenter)
        self.setLayout(self.grid)

        self.check_version()

    def check_version(self):
        latest_version = LauncherSoftware().get_latest_release_version()
        latest_major, latest_minor, latest_bugfix = latest_version.split('.')
        major, minor, bugfix = NODE_LAUNCHER_RELEASE.split('.')

        major_upgrade = latest_major > major

        minor_upgrade = (latest_major == major and latest_minor > minor)

        bugfix_upgrade = (latest_major == major and latest_minor == minor
                          and latest_bugfix > bugfix)

        if major_upgrade or minor_upgrade or bugfix_upgrade:
            self.message_box.setText(UPGRADE)
            self.message_box.setInformativeText(
                f'Your version: {NODE_LAUNCHER_RELEASE}\n'
                f'New version: {latest_version}')
            self.message_box.exec_()

    def change_datadir(self, new_datadir: str):
        self.mainnet_group_box.node_set.bitcoin.file['datadir'] = new_datadir
        self.testnet_group_box.node_set.bitcoin.file['datadir'] = new_datadir
        self.mainnet_group_box.node_set.bitcoin.set_prune()
        self.testnet_group_box.node_set.bitcoin.set_prune()
        self.data_directory_group_box.set_datadir(
            self.mainnet_group_box.node_set.bitcoin.file['datadir'],
            self.mainnet_group_box.node_set.bitcoin.file['prune'])
 def setImageView(self):
     layout = QVBoxLayout()
     self.imageView = QLabel("no video input")
     layout.addWidget(self.imageView)
     self.mainWidget.setLayout(layout)
示例#41
0
            def __init__(self, parent):
                super().__init__(parent)
                self.buttons_id_value = {
                    1: ('comma', ','),
                    2: ('space', '\b'),
                    3: ('tab', '\t'),
                    4: ('semicolon', ';')
                }
                self.separator = QButtonGroup()
                lab = QLabel()
                lab.setText('Choose a separator:')
                for bid, value in self.buttons_id_value.items():
                    self.separator.addButton(QRadioButton(value[0]), id=bid)
                self.separator.setExclusive(True)
                self.default_button = self.separator.button(1)
                button_layout = QHBoxLayout()
                for button in self.separator.buttons():
                    button_layout.addWidget(button)
                self.default_button.click()

                openFileChooser = QPushButton('Choose')
                fileChooser = QFileDialog(self, 'Open csv', str(os.getcwd()),
                                          'Csv (*.csv *.tsv *.dat)')
                fileChooser.setFileMode(QFileDialog.ExistingFile)
                self.filePath = QLineEdit()
                openFileChooser.released.connect(fileChooser.show)
                fileChooser.fileSelected.connect(self.filePath.setText)
                self.filePath.textChanged.connect(self.checkFileExists)
                nameLabel = QLabel('Select a name:', self)
                self.nameField = QLineEdit(self)
                self.nameErrorLabel = QLabel(self)

                self.file_layout = QVBoxLayout()
                fileChooserLayout = QHBoxLayout()
                nameRowLayout = QHBoxLayout()
                fileChooserLayout.addWidget(openFileChooser)
                fileChooserLayout.addWidget(self.filePath)
                nameRowLayout.addWidget(nameLabel)
                nameRowLayout.addWidget(self.nameField)
                self.fileErrorLabel = QLabel(self)
                self.file_layout.addLayout(fileChooserLayout)
                self.file_layout.addWidget(self.fileErrorLabel)
                self.file_layout.addLayout(nameRowLayout)
                self.file_layout.addWidget(self.nameErrorLabel)
                self.fileErrorLabel.hide()
                self.nameErrorLabel.hide()
                self.tablePreview = SearchableAttributeTableWidget(self, True)
                self.tableSpinner = QtWaitingSpinner(
                    self.tablePreview,
                    centerOnParent=True,
                    disableParentWhenSpinning=True)
                self.nameField.textEdited.connect(self.nameErrorLabel.hide)

                # Split file by row
                splitRowLayout = QHBoxLayout()
                self.checkSplit = QCheckBox('Split file by rows', self)
                self.numberRowsChunk = QLineEdit(self)
                self.numberRowsChunk.setPlaceholderText(
                    'Number of rows per chunk')
                self.numberRowsChunk.setValidator(QIntValidator(self))
                splitRowLayout.addWidget(self.checkSplit)
                splitRowLayout.addWidget(self.numberRowsChunk)
                self.checkSplit.stateChanged.connect(self.toggleSplitRows)

                layout = QVBoxLayout()
                layout.addLayout(self.file_layout)
                layout.addWidget(lab)
                layout.addLayout(button_layout)
                layout.addLayout(splitRowLayout)
                layout.addWidget(QLabel('Preview'))
                layout.addWidget(self.tablePreview)
                self.setLayout(layout)

                self.filePath.textChanged.connect(self.loadPreview)
                self.separator.buttonClicked.connect(self.loadPreview)
示例#42
0
    def _setupUI(self):
        self.setWindowTitle("Export Attributes to USD")
        layout = QVBoxLayout()

        # This section contains the attributes tagged for export.
        label = QLabel()
        label.setText('Exported Attributes:')
        layout.addWidget(label)

        self.exportedAttrsModel = ExportedAttributesModel()
        self.exportedAttrsView = ExportedAttributesView()
        self.exportedAttrsView.verticalHeader().hide()
        self.exportedAttrsView.setModel(self.exportedAttrsModel)
        selectionModel = self.exportedAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(
            self._onExportedAttrsSelectionChanged)
        self.exportedAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.exportedAttrsView)

        self.removeExportedAttrButton = QPushButton(
            "Remove Exported Attribute")
        self.removeExportedAttrButton.clicked.connect(
            self._onRemoveExportedAttrPressed)
        self.removeExportedAttrButton.setEnabled(False)
        layout.addWidget(self.removeExportedAttrButton)

        # This section contains the attributes available for export.
        label = QLabel()
        label.setText('Available Attributes:')
        layout.addWidget(label)

        self.userDefinedCheckBox = QCheckBox('User Defined')
        self.userDefinedCheckBox.setToolTip(
            'Show only user-defined (dynamic) attributes')
        self.userDefinedCheckBox.setChecked(True)
        self.userDefinedCheckBox.stateChanged.connect(self._syncUI)
        layout.addWidget(self.userDefinedCheckBox)

        self.addAttrsModel = AddAttributesModel()
        self.addAttrsView = AddAttributesView()
        self.addAttrsView.setModel(self.addAttrsModel)
        selectionModel = self.addAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(
            self._onAddAttrsSelectionChanged)
        self.addAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.addAttrsView)

        self.addExportedAttrButton = QPushButton("Add Exported Attribute")
        self.addExportedAttrButton.clicked.connect(
            self._onAddExportedAttrPressed)
        self.addExportedAttrButton.setEnabled(False)
        layout.addWidget(self.addExportedAttrButton)

        self.setLayout(layout)
示例#43
0
    def __init__(self, app, parent=None):
        super(MainWindow, self).__init__(parent)
        self.imagesDir = app.dir + '/images/'
        self.setWindowIcon(QIcon(self.imagesDir + 'icon.png'))
        self.path = ''

        self.settings = QSettings()
        self.lastDir = self.settings.value('lastDir', '')

        self.setMinimumWidth(540)

        self.supportedFormats = []
        for f in QImageReader.supportedImageFormats():
            self.supportedFormats.append(str(f.data(), encoding="utf-8"))

        self.fileWatcher = QFileSystemWatcher()
        self.fileWatcher.fileChanged.connect(self.fileChanged)

        # widgets
        self.showPixmapWidget = None

        self.tileWidthSpinBox = QSpinBox()
        self.tileWidthSpinBox.setValue(16)
        self.tileWidthSpinBox.setFixedWidth(50)
        self.tileWidthSpinBox.setMinimum(1)

        self.tileHeightSpinBox = QSpinBox()
        self.tileHeightSpinBox.setValue(16)
        self.tileHeightSpinBox.setFixedWidth(50)
        self.tileHeightSpinBox.setMinimum(1)

        self.paddingSpinBox = QSpinBox()
        self.paddingSpinBox.setFixedWidth(50)
        self.paddingSpinBox.setMinimum(1)

        self.transparentCheckbox = QCheckBox("Transparent")
        self.transparentCheckbox.setChecked(True)
        self.transparentCheckbox.stateChanged.connect(self.transparentChanged)

        self.backgroundColorEdit = ColorEdit()
        self.backgroundColorEdit.setEnabled(False)
        self.backgroundColorLabel = QLabel("Background color:")
        self.backgroundColorLabel.setEnabled(False)

        self.forcePotCheckBox = QCheckBox("Force PoT")
        self.forcePotCheckBox.setChecked(True)
        self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged)

        self.reorderTilesCheckBox = QCheckBox("Reorder tiles")

        self.generateAndExportButton = QPushButton("Generate and export")
        self.generateAndExportButton.setFixedHeight(32)
        self.generateAndExportButton.clicked.connect(self.generateAndExportClicked)
        self.generateAndExportButton.setEnabled(False)

        self.pixmapWidget = PixmapWidget()
        self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.pixmapWidget.setPixmap(self.createDropTextPixmap())
        self.pixmapWidget.dropSignal.connect(self.fileDropped)
        self.pixmapWidget.setMinimumHeight(300)

        # load settings
        self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16)))
        self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16)))
        self.paddingSpinBox.setValue(int(self.settings.value('padding', 1)))
        self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False)
        self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False)
        self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False)
        self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF')))
        self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry')))
        self.restoreState(QByteArray(self.settings.value('MainWindow/windowState')))

        # layout
        hl1 = QHBoxLayout()
        hl1.setContentsMargins(5, 5, 5, 5)
        hl1.addWidget(QLabel("Tile width:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileWidthSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Tile height:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileHeightSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Padding:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.paddingSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.forcePotCheckBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.reorderTilesCheckBox)
        hl1.addStretch()

        hl2 = QHBoxLayout()
        hl2.setContentsMargins(5, 5, 5, 5)
        hl2.addWidget(self.transparentCheckbox)
        hl2.addSpacing(15)
        hl2.addWidget(self.backgroundColorLabel)
        hl2.addSpacing(5)
        hl2.addWidget(self.backgroundColorEdit)
        hl2.addStretch()

        hl3 = QHBoxLayout()
        hl3.setContentsMargins(5, 5, 5, 5)
        hl3.addWidget(self.generateAndExportButton)

        vl = QVBoxLayout()
        vl.setContentsMargins(0, 0, 0, 0)
        vl.setSpacing(0)
        vl.addLayout(hl1)
        vl.addLayout(hl2)
        vl.addWidget(self.pixmapWidget)
        vl.addLayout(hl3)

        w = QWidget()
        w.setLayout(vl)
        self.setCentralWidget(w)

        self.setTitle()
class QGroundObjectMenu(QDialog):

    changed = QtCore.Signal()

    def __init__(self, parent, ground_object: TheaterGroundObject,
                 buildings: [], cp: ControlPoint, game: Game):
        super(QGroundObjectMenu, self).__init__(parent)
        self.setMinimumWidth(350)
        self.ground_object = ground_object
        self.buildings = buildings
        self.cp = cp
        self.game = game
        self.setWindowTitle("Location " + self.ground_object.obj_name)
        self.setWindowIcon(EVENT_ICONS["capture"])
        self.intelBox = QGroupBox("Units :")
        self.buildingBox = QGroupBox("Buildings :")
        self.intelLayout = QGridLayout()
        self.buildingsLayout = QGridLayout()
        self.sell_all_button = None
        self.total_value = 0
        self.init_ui()

    def init_ui(self):

        self.mainLayout = QVBoxLayout()
        self.budget = QBudgetBox(self.game)
        self.budget.setGame(self.game)

        self.doLayout()

        if self.ground_object.dcs_identifier == "AA":
            self.mainLayout.addWidget(self.intelBox)
        else:
            self.mainLayout.addWidget(self.buildingBox)

        self.actionLayout = QHBoxLayout()

        self.sell_all_button = QPushButton("Disband (+" +
                                           str(self.total_value) + "M)")
        self.sell_all_button.clicked.connect(self.sell_all)
        self.sell_all_button.setProperty("style", "btn-danger")

        self.buy_replace = QPushButton("Buy/Replace")
        self.buy_replace.clicked.connect(self.buy_group)
        self.buy_replace.setProperty("style", "btn-success")

        if self.total_value > 0:
            self.actionLayout.addWidget(self.sell_all_button)
        self.actionLayout.addWidget(self.buy_replace)

        if self.cp.captured and self.ground_object.dcs_identifier == "AA":
            self.mainLayout.addLayout(self.actionLayout)
        self.setLayout(self.mainLayout)

    def doLayout(self):

        self.update_total_value()
        self.intelBox = QGroupBox("Units :")
        self.intelLayout = QGridLayout()
        i = 0
        for g in self.ground_object.groups:
            if not hasattr(g, "units_losts"):
                g.units_losts = []
            for u in g.units:
                self.intelLayout.addWidget(
                    QLabel("<b>Unit #" + str(u.id) + " - " + str(u.type) +
                           "</b>"), i, 0)
                i = i + 1

            for u in g.units_losts:

                utype = unit_type_of(u)
                if utype in PRICES:
                    price = PRICES[utype]
                else:
                    price = 6

                self.intelLayout.addWidget(
                    QLabel("<b>Unit #" + str(u.id) + " - " + str(u.type) +
                           "</b> [DEAD]"), i, 0)
                if self.cp.captured:
                    repair = QPushButton("Repair [" + str(price) + "M]")
                    repair.setProperty("style", "btn-success")
                    repair.clicked.connect(
                        lambda u=u, g=g, p=price: self.repair_unit(g, u, p))
                    self.intelLayout.addWidget(repair, i, 1)
                i = i + 1
        stretch = QVBoxLayout()
        stretch.addStretch()
        self.intelLayout.addLayout(stretch, i, 0)

        self.buildingBox = QGroupBox("Buildings :")
        self.buildingsLayout = QGridLayout()
        j = 0
        for i, building in enumerate(self.buildings):
            if building.dcs_identifier not in FORTIFICATION_BUILDINGS:
                self.buildingsLayout.addWidget(
                    QBuildingInfo(building, self.ground_object), j / 3, j % 3)
                j = j + 1

        self.buildingBox.setLayout(self.buildingsLayout)
        self.intelBox.setLayout(self.intelLayout)

    def do_refresh_layout(self):
        try:
            for i in range(self.mainLayout.count()):
                item = self.mainLayout.itemAt(i)
                if item is not None and item.widget() is not None:
                    item.widget().setParent(None)
            self.sell_all_button.setParent(None)
            self.buy_replace.setParent(None)
            self.actionLayout.setParent(None)

            self.doLayout()
            if self.ground_object.dcs_identifier == "AA":
                self.mainLayout.addWidget(self.intelBox)
            else:
                self.mainLayout.addWidget(self.buildingBox)

            self.actionLayout = QHBoxLayout()
            if self.total_value > 0:
                self.actionLayout.addWidget(self.sell_all_button)
            self.actionLayout.addWidget(self.buy_replace)

            if self.cp.captured and self.ground_object.dcs_identifier == "AA":
                self.mainLayout.addLayout(self.actionLayout)

        except Exception as e:
            print(e)
        self.update_total_value()
        self.changed.emit()

    def update_total_value(self):
        total_value = 0
        for group in self.ground_object.groups:
            for u in group.units:
                utype = unit_type_of(u)
                if utype in PRICES:
                    total_value = total_value + PRICES[utype]
                else:
                    total_value = total_value + 1
        if self.sell_all_button is not None:
            self.sell_all_button.setText("Disband (+$" +
                                         str(self.total_value) + "M)")
        self.total_value = total_value

    def repair_unit(self, group, unit, price):
        if self.game.budget > price:
            self.game.budget -= price
            group.units_losts = [
                u for u in group.units_losts if u.id != unit.id
            ]
            group.units.append(unit)
            GameUpdateSignal.get_instance().updateGame(self.game)

            # Remove destroyed units in the vicinity
            destroyed_units = self.game.get_destroyed_units()
            for d in destroyed_units:
                p = Point(d["x"], d["z"])
                if p.distance_to_point(unit.position) < 15:
                    destroyed_units.remove(d)
                    logging.info("Removed destroyed units " + str(d))
            logging.info("Repaired unit : " + str(unit.id) + " " +
                         str(unit.type))

        self.do_refresh_layout()
        self.changed.emit()

    def sell_all(self):
        self.update_total_value()
        self.game.budget = self.game.budget + self.total_value
        self.ground_object.groups = []
        self.do_refresh_layout()
        GameUpdateSignal.get_instance().updateBudget(self.game)

    def buy_group(self):
        self.subwindow = QBuyGroupForGroundObjectDialog(
            self, self.ground_object, self.cp, self.game, self.total_value)
        self.subwindow.changed.connect(self.do_refresh_layout)
        self.subwindow.show()
    def _setupUI(self):
        self.setWindowTitle("Export Attributes to USD")
        layout = QVBoxLayout()

        # This section contains the attributes tagged for export.
        label = QLabel()
        label.setText('Exported Attributes:')
        layout.addWidget(label)

        self.exportedAttrsModel = ExportedAttributesModel()
        self.exportedAttrsView = ExportedAttributesView()
        self.exportedAttrsView.verticalHeader().hide()
        self.exportedAttrsView.setModel(self.exportedAttrsModel)
        selectionModel = self.exportedAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(self._onExportedAttrsSelectionChanged)
        self.exportedAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.exportedAttrsView)

        self.removeExportedAttrButton = QPushButton("Remove Exported Attribute")
        self.removeExportedAttrButton.clicked.connect(self._onRemoveExportedAttrPressed)
        self.removeExportedAttrButton.setEnabled(False)
        layout.addWidget(self.removeExportedAttrButton)

        # This section contains the attributes available for export.
        label = QLabel()
        label.setText('Available Attributes:')
        layout.addWidget(label)

        self.userDefinedCheckBox = QCheckBox('User Defined')
        self.userDefinedCheckBox.setToolTip('Show only user-defined (dynamic) attributes')
        self.userDefinedCheckBox.setChecked(True)
        self.userDefinedCheckBox.stateChanged.connect(self._syncUI)
        layout.addWidget(self.userDefinedCheckBox)

        self.addAttrsModel = AddAttributesModel()
        self.addAttrsView = AddAttributesView()
        self.addAttrsView.setModel(self.addAttrsModel)
        selectionModel = self.addAttrsView.selectionModel()
        selectionModel.selectionChanged.connect(self._onAddAttrsSelectionChanged)
        self.addAttrsModel.dataChanged.connect(self._onModelDataChanged)
        layout.addWidget(self.addAttrsView)

        self.addExportedAttrButton = QPushButton("Add Exported Attribute")
        self.addExportedAttrButton.clicked.connect(self._onAddExportedAttrPressed)
        self.addExportedAttrButton.setEnabled(False)
        layout.addWidget(self.addExportedAttrButton)

        self.setLayout(layout)
示例#46
0
class Affichage_GPS(QWidget):
    """docstring for Affichage_GPS."""
    def __init__(self, fen1, Timer):
        super(Affichage_GPS, self).__init__()
        self.fenetre_graph = fen1
        self.Timer = Timer
        tilemapbase.init(create=True)
        self.affichage_carte = False
        self.Latitude = []
        self.Longitude = []
        self.Altitude = []
        self.Position = []

        self.graph = mw.MatplotlibWidget()
        self.plot = self.graph.getFigure()
        #self.plot2 = self.plot.subplots(figsize=(8, 8), dpi=100)
        self.graph.resize(400, 400)

        self.axe = self.plot.add_subplot(111)
        self.axe.axis("off")
        #self.axe.resize(800,800)
        #self.graph.set

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.graph)
        self.setLayout(self.layout)

        #self.Timer.timeout.connect(self.gps_update)
        self.Timer.timeout.connect(self.variable_update)
        #self.Timer.timeout.connect(self.gps_carte_fond)
        self.Timer.timeout.connect(self.gps_waypoints)

    def variable_update(self):
        if self.fenetre_graph.Matrice is not None:
            self.Latitude = self.fenetre_graph.Matrice[1:, 10]
            self.Longitude = self.fenetre_graph.Matrice[1:, 11]
            self.Altitude = self.fenetre_graph.Matrice[1:, 12]

            #print(type(self.Latitude))
            #print(self.Latitude.shape)

    def gps_carte_fond(self):
        #print(self.fenetre_graph.Matrice)

        if self.fenetre_graph.Matrice is not None:
            #print(self.Longitude,self.Latitude)
            self.centre = (self.Longitude[0], self.Latitude[0])
            #self.centre = (-1.7458099,48.0453455)
            self.marge = 0.002
            self.extent = tilemapbase.Extent.from_lonlat(
                self.centre[0] - self.marge, self.centre[0] + self.marge,
                self.centre[1] - self.marge, self.centre[1] + self.marge)
            self.extent = self.extent.to_aspect(1.0)
            self.plotter = tilemapbase.Plotter(self.extent,
                                               tilemapbase.tiles.build_OSM(),
                                               width=400)
            self.plotter.plot(self.axe, tilemapbase.tiles.build_OSM())
            #self.plot.show()
            self.graph.draw()
            self.affichage_carte = True
            #self.fig ,self.ax =

    def gps_waypoints(self):
        if self.fenetre_graph.Matrice is not None:
            self.axe.clear()
            #self.affichage_carte = False
            self.gps_carte_fond()
            #print("nouveau point")
            path = [
                tilemapbase.project(x, y)
                for x, y in zip(self.Longitude, self.Latitude)
            ]
            x, y = zip(*path)
            self.axe.plot(x, y, 'ro-')
            self.axe.axis("off")
            self.graph.draw()
示例#47
0
    def __init__(self, parent, data):
        if not type(data) == BinaryView:
            raise Exception('expected widget data to be a BinaryView')

        self.bv = data

        self.debug_state = binjaplug.get_state(data)
        memory_view = self.debug_state.memory_view
        self.debug_state.ui.debug_view = self

        QWidget.__init__(self, parent)
        self.controls = ControlsWidget.DebugControlsWidget(
            self, "Controls", data, self.debug_state)
        View.__init__(self)

        self.setupView(self)

        self.current_offset = 0

        self.splitter = QSplitter(Qt.Orientation.Horizontal, self)

        frame = ViewFrame.viewFrameForWidget(self)
        self.memory_editor = LinearView(memory_view, frame)
        self.binary_editor = DisassemblyContainer(frame, data, frame)

        self.binary_text = TokenizedTextView(self, memory_view)
        self.is_raw_disassembly = False
        self.raw_address = 0

        self.is_navigating_history = False
        self.memory_history_addr = 0

        # TODO: Handle these and change views accordingly
        # Currently they are just disabled as the DisassemblyContainer gets confused
        # about where to go and just shows a bad view
        self.binary_editor.getDisassembly().actionHandler().bindAction(
            "View in Hex Editor", UIAction())
        self.binary_editor.getDisassembly().actionHandler().bindAction(
            "View in Linear Disassembly", UIAction())
        self.binary_editor.getDisassembly().actionHandler().bindAction(
            "View in Types View", UIAction())

        self.memory_editor.actionHandler().bindAction("View in Hex Editor",
                                                      UIAction())
        self.memory_editor.actionHandler().bindAction(
            "View in Disassembly Graph", UIAction())
        self.memory_editor.actionHandler().bindAction("View in Types View",
                                                      UIAction())

        small_font = QApplication.font()
        small_font.setPointSize(11)

        bv_layout = QVBoxLayout()
        bv_layout.setSpacing(0)
        bv_layout.setContentsMargins(0, 0, 0, 0)

        bv_label = QLabel("Loaded File")
        bv_label.setFont(small_font)
        bv_layout.addWidget(bv_label)
        bv_layout.addWidget(self.binary_editor)

        self.bv_widget = QWidget()
        self.bv_widget.setLayout(bv_layout)

        disasm_layout = QVBoxLayout()
        disasm_layout.setSpacing(0)
        disasm_layout.setContentsMargins(0, 0, 0, 0)

        disasm_label = QLabel("Raw Disassembly at PC")
        disasm_label.setFont(small_font)
        disasm_layout.addWidget(disasm_label)
        disasm_layout.addWidget(self.binary_text)

        self.disasm_widget = QWidget()
        self.disasm_widget.setLayout(disasm_layout)

        memory_layout = QVBoxLayout()
        memory_layout.setSpacing(0)
        memory_layout.setContentsMargins(0, 0, 0, 0)

        memory_label = QLabel("Debugged Process")
        memory_label.setFont(small_font)
        memory_layout.addWidget(memory_label)
        memory_layout.addWidget(self.memory_editor)

        self.memory_widget = QWidget()
        self.memory_widget.setLayout(memory_layout)

        self.splitter.addWidget(self.bv_widget)
        self.splitter.addWidget(self.memory_widget)

        # Equally sized
        self.splitter.setSizes([0x7fffffff, 0x7fffffff])

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.controls)
        layout.addWidget(self.splitter, 100)
        self.setLayout(layout)

        self.needs_update = True
        self.update_timer = QTimer(self)
        self.update_timer.setInterval(200)
        self.update_timer.setSingleShot(False)
        self.update_timer.timeout.connect(lambda: self.updateTimerEvent())

        self.add_scripting_ref()
示例#48
0
    def init_campaign_management_layout(self) -> None:
        campaign_layout = QVBoxLayout()
        campaign_layout.setAlignment(Qt.AlignTop)
        self.campaign_management_page.setLayout(campaign_layout)

        general = QGroupBox("General")
        campaign_layout.addWidget(general)

        general_layout = QGridLayout()
        general.setLayout(general_layout)

        def set_restict_weapons_by_date(value: bool) -> None:
            self.game.settings.restrict_weapons_by_date = value

        restrict_weapons = QCheckBox()
        restrict_weapons.setChecked(
            self.game.settings.restrict_weapons_by_date)
        restrict_weapons.toggled.connect(set_restict_weapons_by_date)

        tooltip_text = (
            "Restricts weapon availability based on the campaign date. Data is "
            "extremely incomplete so does not affect all weapons.")
        restrict_weapons.setToolTip(tooltip_text)
        restrict_weapons_label = QLabel("Restrict weapons by date (WIP)")
        restrict_weapons_label.setToolTip(tooltip_text)

        general_layout.addWidget(restrict_weapons_label, 0, 0)
        general_layout.addWidget(restrict_weapons, 0, 1, Qt.AlignRight)

        automation = QGroupBox("HQ Automation")
        campaign_layout.addWidget(automation)

        automation_layout = QGridLayout()
        automation.setLayout(automation_layout)

        def set_runway_automation(value: bool) -> None:
            self.game.settings.automate_runway_repair = value

        def set_front_line_automation(value: bool) -> None:
            self.game.settings.automate_front_line_reinforcements = value

        def set_aircraft_automation(value: bool) -> None:
            self.game.settings.automate_aircraft_reinforcements = value

        runway_repair = QCheckBox()
        runway_repair.setChecked(self.game.settings.automate_runway_repair)
        runway_repair.toggled.connect(set_runway_automation)

        automation_layout.addWidget(QLabel("Automate runway repairs"), 0, 0)
        automation_layout.addWidget(runway_repair, 0, 1, Qt.AlignRight)

        front_line = QCheckBox()
        front_line.setChecked(
            self.game.settings.automate_front_line_reinforcements)
        front_line.toggled.connect(set_front_line_automation)

        automation_layout.addWidget(QLabel("Automate front-line purchases"), 1,
                                    0)
        automation_layout.addWidget(front_line, 1, 1, Qt.AlignRight)

        aircraft = QCheckBox()
        aircraft.setChecked(
            self.game.settings.automate_aircraft_reinforcements)
        aircraft.toggled.connect(set_aircraft_automation)

        automation_layout.addWidget(QLabel("Automate aircraft purchases"), 2,
                                    0)
        automation_layout.addWidget(aircraft, 2, 1, Qt.AlignRight)
示例#49
0
class ToolBox(QVBoxLayout):

    sig = QtCore.Signal(object)
    listThread = None
    groupBoxThreadInfo = None
    threadvbox = None
    mode = None

    def __init__(self, mode, parentQWidget = None):
        QVBoxLayout.__init__(self)

        self.sig.connect(self.addThreadList)
        self.mode = mode

        self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)

        self.groupBoxSearch = QGroupBox()
        self.groupBoxSearch.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 4px; };")
        vboxSearch = QVBoxLayout()
        self.searchTitle = QLabel("Search Messages")
        vboxSearch.addWidget(self.searchTitle)
        self.searchHLayout = QHBoxLayout()
        self.editTextSearch = QTextEdit('')
        self.editTextSearch.setFixedSize(200,30)
        self.buttonSearch = QPushButton('Search')
        self.buttonSearch.setFixedSize(100,30)
        self.buttonSearch.clicked.connect(self.searchMsg)
        vboxSearch.addWidget(self.editTextSearch)
        self.searchHLayout.addWidget(self.buttonSearch)
        self.searchCursor = QLabel()
        self.searchHLayout.addWidget(self.searchCursor)
        vboxSearch.addLayout(self.searchHLayout)
        self.browseHLayout = QHBoxLayout()
        self.buttonLookUp = QPushButton('\u21e7')  #Arrow up
        self.buttonLookUp.setFixedWidth(100)
        self.buttonLookUp.clicked.connect(self.moveToPrev)
        self.buttonLookDown = QPushButton('\u21e9') #Arrow down
        self.buttonLookDown.setFixedWidth(100)
        self.buttonLookDown.clicked.connect(self.moveToNext)
        self.browseHLayout.addWidget(self.buttonLookUp)
        self.browseHLayout.addWidget(self.buttonLookDown)
        vboxSearch.addLayout(self.browseHLayout)
        self.groupBoxSearch.setLayout(vboxSearch)
        self.addWidget(self.groupBoxSearch)
        self.groupBoxSearch.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.buttonHiddenLifelines = QPushButton('Show hidden life-lines')
        self.buttonHiddenLifelines.setFixedWidth(200)
        self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines)
        self.addWidget(self.buttonHiddenLifelines)

        self.buttonHiddenMessages = QPushButton('Show hidden Messages')
        self.buttonHiddenMessages.setFixedWidth(200)
        self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages)
        self.addWidget(self.buttonHiddenMessages)

        if const.mode_interactive == mode:
            self.buttonCapture = QPushButton('Capture')
            self.buttonCapture.setFixedWidth(200)
            self.buttonCapture.clicked.connect(self.notifyCapture)
            self.addWidget(self.buttonCapture)
        self.msgRcv = []
        self.msgInfo = QLabel("Message Info.")
        self.groupBoxMessageInfo = QGroupBox()
        self.groupBoxMessageInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;")
        vbox = QVBoxLayout()
        vbox.addWidget(self.msgInfo)
        self.tableTime = QTableWidget(3,2)
        self.tableTime.setHorizontalHeaderLabels(['-','time'])
        self.tableTime.setColumnWidth(0,80)
        self.tableTime.setColumnWidth(1,150)
        vwidth = self.tableTime.verticalHeader().length()
        hwidth = self.tableTime.horizontalHeader().height()
        fwidth = self.tableTime.frameWidth() * 2
        self.tableTime.setFixedHeight(vwidth + hwidth + fwidth)
        self.tableTime.horizontalHeader().setStretchLastSection(True)
        self.tableTime.setItem(0,0,QTableWidgetItem('begin'))
        self.tableTime.setItem(0,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(1,0,QTableWidgetItem('end'))
        self.tableTime.setItem(1,1,QTableWidgetItem(' - '))
        self.tableTime.setItem(2,0,QTableWidgetItem('duration'))
        self.tableTime.setItem(2,1,QTableWidgetItem(' - '))
        vbox.addWidget(self.tableTime)

        self.titleArg = QLabel('Argument List')
        vbox.addWidget(self.titleArg)

        max_arg_num = 10
        self.tableArgs = QTableWidget(max_arg_num,2)
        self.tableArgs.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_arg_num):
            self.tableArgs.setItem(idx,0,QTableWidgetItem())
            self.tableArgs.setItem(idx,1,QTableWidgetItem())
        self.tableArgs.horizontalHeader().setStretchLastSection(True)
        vbox.addWidget(self.tableArgs)

        self.titleArg = QLabel('Return Value List')
        vbox.addWidget(self.titleArg)

        max_ret_num = 4
        self.tableRet = QTableWidget(max_ret_num,2)
        self.tableRet.setHorizontalHeaderLabels(['type','value'])
        for idx in range(0,max_ret_num):
            self.tableRet.setItem(idx,0,QTableWidgetItem())
            self.tableRet.setItem(idx,1,QTableWidgetItem())
        self.tableRet.horizontalHeader().setStretchLastSection(True)
        vwidth = self.tableRet.verticalHeader().length()
        hwidth = self.tableRet.horizontalHeader().height()
        fwidth = self.tableRet.frameWidth() * 2
        self.tableRet.setFixedHeight(vwidth + hwidth + fwidth)
        vbox.addWidget(self.tableRet)

        self.buttonSrcView = QPushButton('view code')
        self.buttonSrcView.setFixedWidth(200)
        self.buttonSrcView.clicked.connect(self.openSourceViewer)
        self.buttonHide = QPushButton('Hide')
        self.buttonHide.setFixedWidth(200)
        self.buttonHide.clicked.connect(self.notifyHide)
        self.buttonHideAllMsg = QPushButton('Hide All')
        self.buttonHideAllMsg.setFixedWidth(200)
        self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected)
        self.groupBoxMessageInfo.setLayout(vbox)
        self.checkHideCircular = QCheckBox('Hide Circular Messages')
        self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked)
        self.checkHideCircular.stateChanged.connect(self.changeHideCircularMessage)
        self.addWidget(self.checkHideCircular)
        self.addWidget(self.groupBoxMessageInfo)
        self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy)

    def reset(self):
        for idx in reversed(range(0,self.listThread.count())):
            self.listThread.takeItem(idx)

    def setMsgInfoMessage(self,msg):
        self.strMessage = msg

    def changeHideCircularMessage(self,state):
        if state == QtCore.Qt.Unchecked:
            self.diagramView.hideCircularChanged(False)
        elif state == QtCore.Qt.Checked:
            self.diagramView.hideCircularChanged(True)
    
    def setMsgInfoModule(self,module):
        self.strModule = module

    def updateSearchStatus(self,curr,number):
        self.searchCursor.setText("%d/%d" % (curr,number))

    def connectSourceViewer(self,viewer):
        self.srcViewer = viewer

    def openSourceViewer(self):
        self.srcViewer.openViewer(self.strModule,self.strMessage)

    def setMessageInfoTime(self,begin,end,duration):
        self.tableTime.item(0,1).setText(begin)
        self.tableTime.item(1,1).setText(end)
        self.tableTime.item(2,1).setText(duration + ' msec')

    def setMessageInfoArg(self,listParam,listArg):
        # Clear the contents in the table
        max_arg_num = 10
        for idx in range(0,max_arg_num):
            self.tableArgs.item(idx,0).setText('')
            self.tableArgs.item(idx,1).setText('')

        if listArg:
            for idx, text in enumerate(listArg):
                self.tableArgs.item(idx,1).setText(text)
            for idx, text in enumerate(listParam):
                self.tableArgs.item(idx,0).setText(text)
        else:
            for idx in range(0,self.tableArgs.rowCount()):
                self.tableArgs.item(idx,1).setText('')
                self.tableArgs.item(idx,0).setText('')

    def setMessageInfoRet(self,listRet):
        if listRet:
            for idx, text in enumerate(listRet):
                self.tableRet.item(idx,1).setText(text)
        else:
            for idx in range(0,self.tableRet.rowCount()):
                self.tableRet.item(idx,1).setText('')
                self.tableRet.item(idx,0).setText('')

    def notifyInteractiveStateChanged(self,state):
        if const.mode_interactive != self.mode:
            return

        if const.STATE_INTERACTIVE_CAPTURING == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Stop Capture')
        if const.STATE_INTERACTIVE_PROCESSING == state:
            self.buttonCapture.setEnabled(False)
        if const.STATE_INTERACTIVE_IDLE == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Capture')
        if const.STATE_INTERACTIVE_RESET == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Capture')
        elif const.STATE_INTERACTIVE_ACTIVE == state:
            self.buttonCapture.setEnabled(True)
            self.buttonCapture.setText('Capture')

    def setMessageInfo(self,info):
        self.msgInfo.setText(info)

    def setAvailable(self,threads):
        self.sig.emit(threads)

    def toggleThreadDisplay(self,item):
        print(self.listThread.currentRow())
        #if item.isSelected():
        #    print(item.text() + "  is selected")
        #else:
        #    print(item.text() + "  is not selected")
        self.diagramView.showThread(self.listThread.currentRow(),item.isSelected())

    def hideAllMsgNamedAsSelected(self):
        self.diagramView.hideAllMessageSelected()

    def addThreadList(self,threads):

        if not self.groupBoxThreadInfo:
            self.groupBoxThreadInfo = QGroupBox()
            self.threadInfo = QLabel("Thread Info.")
            self.groupBoxThreadInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;")

        if not self.threadvbox:
            self.threadvbox = QVBoxLayout()

        if not self.listThread:
            self.listThread = QListWidget()
            
        self.listThread.setFixedWidth(200)
        self.listThread.setSelectionMode(QAbstractItemView.MultiSelection)
        QtCore.QObject.connect(self.listThread, QtCore.SIGNAL("itemClicked(QListWidgetItem *)"), self.toggleThreadDisplay)
        self.threadvbox.addWidget(self.threadInfo)
        self.threadvbox.addWidget(self.listThread)
        self.groupBoxThreadInfo.setLayout(self.threadvbox)
        self.addWidget(self.groupBoxThreadInfo)
        self.groupBoxThreadInfo.setSizePolicy(self.sizePolicy)

        for id in threads:
            item = QListWidgetItem(id)
            self.listThread.addItem(item)

    def connectController(self,controller):
        self.controller = controller
        self.connect(controller,QtCore.SIGNAL('setAvailable()'),self.setAvailable)
       
    def connectDiagramView(self,view):
        self.diagramView = view
 
    def disconnectMsgRcv(self,receiver):
        print("Implement this method !!! disconnectMsgRcv")

    def connectMsgRcv(self,receiver):
        self.msgRcv.append(receiver)

    def notifyHide(self):
        for rcv in self.msgRcv:
            rcv.activateHide(True)

    def showHiddenLifelines(self):
        response, selected_items = HiddenDialog.HiddenDialog.getSelectedItems(self.diagramView.getHiddenLifeLines())
        if response:
            self.diagramView.showLifelines(selected_items)

    def showHiddenMessages(self):
        response, selected_items = HiddenMessageDialog.HiddenMessageDialog.getSelectedItems(self.diagramView.getHiddenMessages(),self.diagramView.getHiddenLifeLines())
        if response:
            if selected_items[3] in self.diagramView.getHiddenLifeLines():
                confirmation = ShowLifeLineDialog.ShowLifeLineDialog.confirmToShowLifeLine(selected_items[3])
                if confirmation:
                    self.diagramView.showLifelines([selected_items[3]])
                    self.diagramView.showMessages(selected_items)
            else:
                self.diagramView.showMessages(selected_items)

    def notifyCapture(self):
        for rcv in self.msgRcv:
            rcv.activateCapture(True)
    
    def moveToPrev(self):
        for rcv in self.msgRcv:
            rcv.moveToPrev()
        
    def moveToNext(self):
        for rcv in self.msgRcv:
            rcv.moveToNext()

    def searchMsg(self):
        str = self.editTextSearch.toPlainText()
        for rcv in self.msgRcv:
            rcv.searchMessage(str)
示例#50
0
class BrowserDialog(QMainWindow):
    logMessage = Signal(str)
    captureData = Signal(dict, dict, dict)
    newCookie = Signal(str, str)

    #loadFinished = Signal(bool)
    #urlChanged = Signal(str)
    #urlNotFound = Signal(QUrl)

    def __init__(self, parent=None, caption="", width=600, height=600):
        super(BrowserDialog, self).__init__(parent)

        self.setAttribute(Qt.WA_DeleteOnClose)
        self.resize(width, height)
        self.setWindowTitle(caption)

        self.url = None
        self.domain = None
        self.headers = {}
        self.stopped = False
        self.cookie = ''
        self.ready = False

        central = QWidget()
        self.setCentralWidget(central)
        self.mainLayout = QVBoxLayout(central)

        self.topLayout = QHBoxLayout()
        self.mainLayout.addLayout(self.topLayout)

        # Status bar
        self.statusBar = self.statusBar()
        self.cookieLabel = QScrollLabel()
        self.cookieLabel.setSizePolicy(QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Ignored)
        self.statusBar.addWidget(self.cookieLabel)
        self.cookieLabel.textVisible(False)

        self.loadingLabel = QLabel()
        self.statusBar.addPermanentWidget(self.loadingLabel)

        # Adress bar
        self.addressBar = QLineEdit()
        self.addressBar.returnPressed.connect(self.addressChanged)
        self.topLayout.addWidget(self.addressBar)
        self.addressBar.setVisible(False)

        # Create WebView
        self.webview = QWebEngineView(self)
        QWebEngineSettings.globalSettings().setAttribute(
            QWebEngineSettings.PluginsEnabled, True)
        QWebEngineSettings.globalSettings().setAttribute(
            QWebEngineSettings.ScreenCaptureEnabled, True)
        self.webpage = WebPageCustom(self.webview)
        self.webview.setPage(self.webpage)
        self.mainLayout.addWidget(self.webview)
        self.webview.show()

        # Signals
        self.webpage.logMessage.connect(self.logMessage)
        self.webpage.cookieChanged.connect(self.cookieChanged)
        self.webview.urlChanged.connect(self.urlChanged)
        self.webpage.loadFinished.connect(self.loadFinished)
        self.webpage.loadStarted.connect(self.loadStarted)

        #self.webpage.urlNotFound.connect(self.urlNotFound)
        #self.browserWebview.loadFinished.connect(self.loadFinished)
        #self.browserWebview.loadStarted.connect(self.loadStarted)

        # Button layout
        self.buttonLayout = QHBoxLayout()
        self.topLayout.addLayout(self.buttonLayout)

        # Buttons
        buttonDismiss = QPushButton(self)
        buttonDismiss.setText("Close")
        buttonDismiss.setDefault(True)
        buttonDismiss.clicked.connect(self.close)
        self.buttonLayout.addWidget(buttonDismiss)

    def loadPage(self,
                 url="",
                 headers={},
                 options={},
                 foldername=None,
                 filename=None,
                 fileext=None):

        self.url = url
        self.headers = headers
        self.options = options
        self.strip = self.options.get('access_token', '')

        self.foldername = foldername
        self.filename = filename
        self.fileext = fileext

        try:
            targeturl = urllib.parse.urlparse(url)
            self.domain = targeturl.netloc
        except:
            self.domain = None

        request = QWebEngineHttpRequest(QUrl(self.url))
        for key, val in self.headers.items():
            key = key.encode('utf-8')
            val = val.encode('utf-8')
            request.setHeader(QByteArray(key), QByteArray(val))

        self.webview.load(request)
        self.show()

    @Slot()
    def loadStarted(self):
        self.ready = False
        self.loadingLabel.setText('Loading...')

    @Slot()
    def loadFinished(self, ok):
        if ok:
            self.ready = True

            self.loadingLabel.setText('Loading finished.')
        else:
            self.ready = False
            self.loadingLabel.setText('Loading failed.')

    @Slot()
    def urlChanged(self, url):
        url = url.toString().replace(self.strip, '')
        self.addressBar.setText(url)

    @Slot()
    def addressChanged(self):
        url = self.addressBar.text()
        request = QWebEngineHttpRequest(QUrl(url))
        self.webview.load(request)

    # Scrape HTML
    def activateCaptureButton(self, handler):
        self.captureData.connect(handler)

        buttonCapture = QPushButton(self)
        buttonCapture.setText("Capture")
        buttonCapture.setDefault(True)
        buttonCapture.clicked.connect(self.captureDataClicked)
        self.buttonLayout.addWidget(buttonCapture)

        self.addressBar.setVisible(True)

    @Slot()
    def captureDataClicked(self):

        # Metadata
        data = {}
        data['title'] = self.webpage.title()

        try:
            data['url'] = {
                'final':
                self.webpage.url().toString().replace(self.strip, ''),
                'requested':
                self.webpage.requestedUrl().toString().replace(self.strip, '')
            }

            # Fetch HTML
            data['html'] = self.getHtml()

            # Fetch plain text
            data['text'] = self.getText()

            if self.foldername is not None:

                # Screenshot
                try:
                    fullfilename = makefilename(data['url']['final'],
                                                self.foldername,
                                                self.filename,
                                                fileext='.png',
                                                appendtime=True)
                    data['screenshot'] = self.getScreenShot(fullfilename)
                except Exception as e:
                    self.logMessage.emit('Error capturing screenshot: ' +
                                         str(e))

                # HTML file
                try:
                    fullfilename = makefilename(data['url']['final'],
                                                self.foldername,
                                                self.filename,
                                                self.fileext,
                                                appendtime=True)
                    file = open(fullfilename, 'wb')
                    if file is not None:
                        try:
                            file.write(data['text'].encode())
                        finally:
                            file.close()
                except Exception as e:
                    self.logMessage.emit('Error saving HTML: ' + str(e))

                # PDF
                try:
                    fullfilename = makefilename(data['url']['final'],
                                                self.foldername,
                                                self.filename,
                                                fileext='.pdf',
                                                appendtime=True)
                    self.webpage.printToPdf(fullfilename)
                    data['pdf'] = fullfilename
                except Exception as e:
                    self.logMessage.emit('Error printing to PDF: ' + str(e))

        except Exception as e:
            data['error'] = str(e)
            self.logMessage.emit(str(e))

        # Options
        options = self.options
        options['querytime'] = str(datetime.now())
        options['querystatus'] = 'captured'
        options['querytype'] = 'captured'
        #options['objectid'] = 'url.final'
        #options['nodedata'] = None

        # Headers
        headers = {}

        self.captureData.emit(data, options, headers)

    def getHtml(self):
        def newHtmlData(html):
            self.capturedhtml = html

        self.capturedhtml = None
        self.webpage.toHtml(newHtmlData)

        waitstart = QDateTime.currentDateTime()
        while (self.capturedhtml is None) and (waitstart.msecsTo(
                QDateTime.currentDateTime()) < 1000):
            QApplication.processEvents()
            time.sleep(0.01)

        return self.capturedhtml

    def getText(self):
        def newTextData(txt):
            self.capturedtext = txt

        self.capturedtext = None
        self.webpage.toPlainText(newTextData)

        waitstart = QDateTime.currentDateTime()
        while (self.capturedtext is None) and (waitstart.msecsTo(
                QDateTime.currentDateTime()) < 1000):
            QApplication.processEvents()
            time.sleep(0.01)

        return self.capturedtext

    # https://stackoverflow.com/questions/55231170/taking-a-screenshot-of-a-web-page-in-pyqt5
    #screenshots: https://stackoverrun.com/de/q/12970119

    def getScreenShot(self, filename):
        try:
            # Resize
            oldSize = self.webview.size()
            newSize = self.webpage.contentsSize().toSize()
            self.webview.settings().setAttribute(
                QWebEngineSettings.ShowScrollBars, False)
            self.webview.setAttribute(Qt.WA_DontShowOnScreen, True)
            self.webview.resize(newSize)
            #self.webview.repaint()
            #self.webview.show()

            # Wait for resize
            waitstart = QDateTime.currentDateTime()
            while (waitstart.msecsTo(QDateTime.currentDateTime()) < 500):
                QApplication.processEvents()
                time.sleep(0.01)

            # Capture
            pixmap = QPixmap(newSize)
            self.webview.render(pixmap, QPoint(0, 0))
            pixmap.save(filename, 'PNG')

            self.webview.resize(oldSize)
            self.webview.setAttribute(Qt.WA_DontShowOnScreen, False)
            self.webview.settings().setAttribute(
                QWebEngineSettings.ShowScrollBars, True)
            self.repaint()

        except Exception as e:
            self.logMessage.emit(str(e))

        return filename

    # Get cookie from initial domain
    def activateCookieButton(self, handler):
        self.newCookie.connect(handler)

        self.cookieLabel.textVisible(True)
        buttonCookie = QPushButton(self)
        buttonCookie.setText("Transfer cookie")
        buttonCookie.setDefault(True)
        buttonCookie.clicked.connect(self.transferCookieClicked)
        self.buttonLayout.addWidget(buttonCookie)

        self.addressBar.setVisible(True)

    @Slot()
    def transferCookieClicked(self):
        self.newCookie.emit(self.domain, self.cookie)

    @Slot(str, str)
    def cookieChanged(self, domain, cookie):
        if domain == self.domain:
            self.cookie = cookie
            self.cookieLabel.setText("Cookie for domain: " + domain + ": " +
                                     cookie)