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)
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)
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)
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)
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)
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()
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
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")
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)
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()
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)
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)
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)
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()
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)
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)
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
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()
def _add_grouped(self, form, title, widget): box = QGroupBox(title) vbox = QVBoxLayout() vbox.addWidget(widget) box.setLayout(vbox) form.addRow(box)
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)
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.')
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
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)
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()
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) + ")")
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)
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)
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()
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)
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)
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)
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)
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)
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)
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)
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)
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)
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()
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()
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)
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)
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)