class CreateSeedWizardPage(QWizardPage): def __init__(self, parent=None): super(CreateSeedWizardPage, self).__init__(parent) self.parent = parent self.setTitle(_('PrivateSend Kestore Seed')) self.setSubTitle(_('Your wallet generation seed is:')) self.layout = QVBoxLayout() self.setLayout(self.layout) self.main_widget = QWidget() self.layout.addWidget(self.main_widget) def initializePage(self): self.layout.removeWidget(self.main_widget) self.main_widget.setParent(None) self.main_widget = QWidget() self.layout.addWidget(self.main_widget) self.parent.seed_text = mnemonic.Mnemonic('en').make_seed('standard') self.slayout = SeedLayout(seed=self.parent.seed_text, msg=True, options=['ext']) self.main_widget.setLayout(self.slayout) def nextId(self): if self.slayout.is_ext: return self.parent.REQUEST_PASS_PAGE else: return self.parent.CONFIRM_SEED_PAGE def validatePage(self): self.parent.is_ext = self.slayout.is_ext self.parent.is_restore = False return True
class ContainerWidget(QWidget): """docstring for ContainerWidget""" def __init__(self, **args): super(ContainerWidget, self).__init__() # props self.players = [] # main layout self.mainLayout = QVBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) def addPlayer(self, conf=''): player = PlayerWidget() self.players.append(player) player.initData(args=conf) self.mainLayout.addWidget(player) def initData(self, **args): self.reset() if 'args' in args: args = args['args'] if 'conf' in args: confs = args['conf'] for conf in confs: self.addPlayer(conf) def reset(self): for p in self.players: self.mainLayout.removeWidget(p) p.reset() pass
def __init__(self, parent=None): super(DraftWindow, self).__init__() fbox = QVBoxLayout(self) fbox.addWidget(self.tools) self.myQListWidget = QListWidget(self) self.myQListWidget.showMaximized() for name, message, icon in [ ('Meyoko', 'hello...', 'images/sign.png'), ('Nyaruko', 'how are you..', 'images/sign.png'), ('Louise', 'Dear friend', 'images/sign.png'), ('mily', 'hello...', 'images/sign.png') ]: # Create QCustomQWidget myQCustomQWidget = QCustomQWidget() myQCustomQWidget.setTextUp(name) myQCustomQWidget.setTextDown(message) myQCustomQWidget.setIcon(icon) # Create QListWidgetItem myQListWidgetItem = QListWidgetItem(self.myQListWidget) # Set size hint myQListWidgetItem.setSizeHint(myQCustomQWidget.sizeHint()) # Add QListWidgetItem into QListWidget self.myQListWidget.addItem(myQListWidgetItem) self.myQListWidget.setItemWidget(myQListWidgetItem, myQCustomQWidget) fbox.removeWidget(self.myQListWidget) fbox.addWidget(self.myQListWidget)
class ToolStation(FixedWidthFrame): def __init__(self, controller, model): self.controller = controller self.model = model self.width = self.model.view_data.width super().__init__(self.width) self._init__UI() def _init__UI(self): self.layout = QVBoxLayout() self.layout.setSpacing(4) self.layout.setContentsMargins(1, 1, 1, 1) self.layout.setAlignment(Qt.AlignTop) self.setLayout(self.layout) self._add_all_widgets() def set_data(self): self._remove_all_widgets() self._add_all_widgets() def _add_all_widgets(self) -> None: widgets = self.model.view_data.tools for widget in widgets: seperator = FixedSizeLabel(self.width - 12, 1) seperator.set_colours(Colour(240, 240, 240), Colour(240, 240, 240)) self.layout.addWidget(widget, alignment=Qt.AlignHCenter) self.layout.addWidget(seperator, alignment=Qt.AlignHCenter) def _remove_all_widgets(self) -> None: for index in reversed(range(self.layout.count())): widget = self.layout.itemAt(index).widget() self.layout.removeWidget(widget)
class AnalysisResultOverview(QWidget): result_selected = pyqtSignal() def __init__(self, parent): super(AnalysisResultOverview, self).__init__(parent) self._image_name = None self._analysis_results = None self.layout = QVBoxLayout() self.setLayout(self.layout) self._tabs = None def _setup_tabs(self): if self._tabs is not None: self.layout.removeWidget(self._tabs) self._tabs.destroy() image_slices = self._analysis_results['slices'] if len(image_slices) > 0: self._tabs = QTabWidget(self) for index, image_slice in enumerate(image_slices): intensities = image_slice['intensities'] self._tabs.addTab( Plotter(self._tabs, intensities, range(len(intensities))), f"Slice {str(index)}") self.layout.addWidget(self._tabs) def set_analysis_results(self, results): self._analysis_results = results image_intensities = results['image']['intensities'] self.layout.addWidget( Plotter(self, image_intensities, range(len(image_intensities)))) self._setup_tabs() button = QPushButton("Add this image to the results") button.clicked.connect(lambda: self.result_selected.emit()) self.layout.addWidget(button)
class TabList(QWidget): items = [] def __init__(self): super(QWidget, self).__init__() self.initUI() def initUI(self): self.itemLayout = QVBoxLayout() self.itemLayout.setAlignment(Qt.AlignTop) self.itemLayout.setSpacing(20) self.setLayout(self.itemLayout) def addItem(self, linkLabel): self.itemLayout.addWidget(linkLabel) self.items.append(linkLabel) def removeItem(self): for item in self.items: try: self.itemLayout.removeWidget(item) item.deleteLater() except Exception as ex: print(ex) self.items = [] pass
class ResultDataVisualization(QWidget): def __init__(self, parent): super(ResultDataVisualization, self).__init__() self.setParent(parent) self._image_data = {} self._slices_data = [] self.layout = QVBoxLayout() self.setLayout(self.layout) self._tabs = None def _set_slices_data(self): if self._tabs is not None: self.layout.removeWidget(self._tabs) self._tabs.deleteLater() if len(self._slices_data) > 0: self._tabs = QTabWidget(self) for index, slice_data in enumerate(self._slices_data): self._tabs.addTab(ResultDataTable(self._tabs, slice_data), f"Slice {str(index)}") self.layout.addWidget(self._tabs) def set_data(self, image_data, slices_data): self._image_data = image_data self._slices_data = slices_data self.layout.addWidget(ResultDataTable(self, self._image_data)) self._set_slices_data()
class ResultsList(QScrollArea): def __init__(self): super(ResultsList, self).__init__() self.setMaximumWidth(250) central = QWidget() self.setWidget(central) self.setWidgetResizable(True) self.layout = QVBoxLayout(central) self.layout.addStretch() self.widgets = [] timing.new_solve.register(self.new_solve) timing.discipline_changed.register(self.discipline_changed) def new_solve(self, solve, records): self.widgets.append(ResultWidget(self, solve)) self.layout.insertWidget(0, self.widgets[-1]) def remove_widget(self, widget): self.layout.removeWidget(widget) widget.setParent(None) def discipline_changed(self): for w in self.widgets: self.remove_widget(w) self.widgets = []
class KeySetup(QGroupBox): def __init__(self, parent: QWidget = None): super(KeySetup, self).__init__(parent=parent) self.setup_ui() def setup_ui(self): self.setTitle('Key Setup') self.layout = QVBoxLayout() self.key_input = KeyWidgetFactory.create_key_setup_widget( EngineType.RSA) self.layout.addWidget(self.key_input) self.layout.setSpacing(20) self.setLayout(self.layout) def get_key(self, is_private: bool) -> Key: return self.key_input.build_key(is_private) @pyqtSlot(object) def on_update_key_setup_widget(self, engine_type: EngineType): self.layout.removeWidget(self.key_input) self.key_input.deleteLater() self.key_input = KeyWidgetFactory.create_key_setup_widget(engine_type) self.layout.addWidget(self.key_input)
class ScrollWidget(QScrollArea): def __init__(self): super(ScrollWidget, self).__init__() self._numWidget = 0 self._layout = QVBoxLayout() self._layout.addStretch(1) self._mainW = QWidget() self._mainW.setLayout(self._layout) self.setWidget(self._mainW) self.setWidgetResizable(True) def addWidgetItem(self, widget: QWidget, isTail=False): if isTail: self._layout.insertWidget(self._numWidget, widget) else: self._layout.insertWidget(0, widget) self._numWidget += 1 def delWidgetItem(self, widget: QWidget): self._layout.removeWidget(widget) self._numWidget -= 1 def resizeEvent(self, e: QResizeEvent): super().resizeEvent(e) width = e.size().width() if width > 0: self._mainW.setMaximumWidth(width)
class GuitarPanel(InstrumentPanel): def __init__(self): super().__init__(GuitarInstrument()) self.name = 'Guitar' self.initUI() def initUI(self): self.vbox = QVBoxLayout() # 往上对齐 self.vbox.setAlignment(Qt.AlignTop) self.fb = GuitarBoard(self.instrument, 21) self.fb.displayNote(None, None, 0, 20) self.fl = QVBoxLayout() self.fl.addWidget(self.fb) # 垂直布局 self.vbox.addLayout(self.fl) self.vbox.addWidget(self.detail) self.setLayout(self.vbox) def initPanel(self, num, notes=None, mode='-', position='C'): self.fl.removeWidget(self.fb) self.fb.deleteLater() self.currentNum = num self.fb = GuitarBoard(self.instrument, self.currentNum) self.fb.displayPatternNote(notes, mode, position) self.fl.addWidget(self.fb)
class Pane(QScrollArea): def __init__(self, alignment=0, parent=None): super().__init__(parent) self.mainWidget = QWidget(self) self.mainLayout = QVBoxLayout(self.mainWidget) self.mainLayout.setAlignment(alignment) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.setContentsMargins(0, 0, 0, 0) self.setFrameStyle(QFrame.NoFrame) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.setWidgetResizable(True) self.setWidget(self.mainWidget) def wheelEvent(self, ev): modifiers = QApplication.keyboardModifiers() if modifiers == Qt.ControlModifier: return False super(Pane, self).wheelEvent(ev) def addWidget(self, widget): self.mainLayout.addWidget(widget) def removeWidget(self, widget): self.mainLayout.removeWidget(widget)
class SpaceView(QWidget): """docstring for AbstractSpaceDialog""" def __init__(self): QWidget.__init__(self) print('created win') self.setObjectName("space_view") #self.resize(379, 456) print('resized win') #self.main.setCentralWidget(self) self.vert_layout = QVBoxLayout(self) self.setLayout(self.vert_layout) #self.lineEdit = QLineEdit(self) #self.vert_layout.addWidget(self.lineEdit) self.list_view = None #self.show() def remove_populated_list(self): if self.list_view is not None: t = time() self.vert_layout.removeWidget(self.list_view) print(ftime('remove old listbox\t{}',t)) def create_list(self, items): self.list_view = QListWidget() self.list_view.addItems(items) self.vert_layout.addWidget(self.list_view) self.show() def accomodate_size(self): pass
class CommodityBox(QGroupBox): changed = pyqtSignal() def __init__(self, options, title="Commodities"): super(CommodityBox, self).__init__(title) self.options = options self.options.reset.connect(self.reset) self.setToolTip("Show only selected commodities") self.setCheckable(True) self.setChecked(False) self.toggled.connect(self.changed) self.layout = QVBoxLayout(self) self.checkboxes = {} def __contains__(self, commodity): if not self.isChecked(): return True checkbox = self.checkboxes.get(commodity) return checkbox and checkbox.isChecked() def reset(self): for checkbox in self.checkboxes.values(): self.layout.removeWidget(checkbox) self.checkboxes = {} commodities = self.options.journal.commodities for commodity in commodities.keys(): checkbox = QCheckBox(commodity, self) self.checkboxes[commodity] = checkbox self.layout.addWidget(checkbox) checkbox.stateChanged.connect(self.changed)
class ControllerWindow(QWidget): def __init__(self, flags, stylesheet, *args, **kwargs): super().__init__(flags, *args, **kwargs) self.setStyleSheet(stylesheet) self.current_game_widget: Union[None, QWidget] = None self.serial = self.init_serial() self.game_layout = QVBoxLayout() self.game_layout.setAlignment(Qt.AlignTop) self.game_selector = GameSelector(stylesheet) self._layout = QHBoxLayout() self._layout.addWidget(self.game_selector) self._layout.addLayout(self.game_layout) self.setLayout(self._layout) self.game_selector.buzzer_game_button.clicked.connect( self.on_start_buzzer) self.game_selector.video_question_game.clicked.connect( self.on_start_video) self.game_selector.read_questions_game.clicked.connect( self.on_start_freestyle) def swap_current_game_widget(self, new_game_widget): if self.current_game_widget: self.current_game_widget.hide() self.game_layout.removeWidget(self.current_game_widget) self.current_game_widget = new_game_widget if new_game_widget: self.game_layout.addWidget(new_game_widget) self.raise_() def on_start_buzzer(self): buzzer_game_window = WebcamBuzzerGame(self.serial, self.styleSheet()) buzzer_game_window.setStyleSheet(self.styleSheet()) self.swap_current_game_widget(buzzer_game_window) def on_start_video(self): video_questions_game = VideoQuestionsGame(self.serial, self.styleSheet()) self.serial.write("f".encode()) self.swap_current_game_widget(video_questions_game) def on_start_freestyle(self): self.serial.write("f".encode()) self.swap_current_game_widget(None) @staticmethod def init_serial(): port = QtSerialPort.QSerialPort( '/dev/ttyUSB0', baudRate=QtSerialPort.QSerialPort.Baud9600) port.open(QtCore.QIODevice.ReadWrite) return port
class DirList(QWidget): """DirList UI control """ def __init__(self, values, onChange=None, rowType=DirectoryLocal): super().__init__() self.rowType = rowType self.scroll = QScrollArea(self) self.scroll.setWidgetResizable(True) self.scroll.setFrameShape(QFrame.NoFrame) layout = QVBoxLayout(self.scroll) self.list = QVBoxLayout() self.button = QPushButton('Add') self.button.clicked.connect(self.on_click) layout.addLayout(self.list) layout.addWidget(self.button) layout.addStretch() widget = QWidget() widget.setLayout(layout) self.scroll.setWidget(widget) self.layout = layout self.onChange = onChange for value in values: self.add(value) def resizeEvent(self, _): self.scroll.setFixedWidth(self.width()) self.scroll.setFixedHeight(self.height()) def on_click(self): self.add(None) def add(self, value): self.list.addWidget(Row(self, value, self.rowType)) def save(self): if self.onChange: self.onChange(self) def removeWidget(self, widget): self.list.removeWidget(widget) widget.setParent(None) self.save() def count(self): return self.list.count() def itemAt(self, i): return self.list.itemAt(i) def getValue(self, i): return self.itemAt(i).widget().getValue()
class MessageView(QWidget): """Widget which stacks error/warning/info messages.""" update_geometry = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self._clear_timer = QTimer() self._clear_timer.timeout.connect(self._clear_messages) self._set_clear_timer_interval() objreg.get('config').changed.connect(self._set_clear_timer_interval) self._last_text = None self._messages = [] def sizeHint(self): """Get the proposed height for the view.""" height = sum(label.sizeHint().height() for label in self._messages) # The width isn't really relevant as we're expanding anyways. return QSize(-1, height) @config.change_filter('ui', 'message-timeout') def _set_clear_timer_interval(self): """Configure self._clear_timer according to the config.""" self._clear_timer.setInterval(config.get('ui', 'message-timeout')) @pyqtSlot() def _clear_messages(self): """Hide and delete all messages.""" for widget in self._messages: self._vbox.removeWidget(widget) widget.hide() widget.deleteLater() self._messages = [] self._last_text = None self.hide() self._clear_timer.stop() @pyqtSlot(usertypes.MessageLevel, str) def show_message(self, level, text): """Show the given message with the given MessageLevel.""" if text == self._last_text: return widget = Message(level, text, parent=self) self._vbox.addWidget(widget) widget.show() self._clear_timer.start() self._messages.append(widget) self._last_text = text self.show() self.update_geometry.emit()
class ModulGroup(QScrollArea): def __init__(self, parent=None): super().__init__(parent) self.set_modul(None) self.setWidgetResizable(True) self.group_modul = QGroupBox(self) self.group_layout = QVBoxLayout(self.group_modul) self.group_layout.setAlignment(Qt.AlignTop) self.setWidget(self.group_modul) self._widget_list = [] self._rounding = 10**10 # set modul def set_modul(self, modul): self._modul = modul # nambah widget def add_widget(self): if self._modul is not None: modul = self._modul() perhitungan_widget = PerhitunganWidget(self.group_modul, modul) perhitungan_widget.do_remove_widget.connect(self.remove_widget) perhitungan_widget.set_rounding(self._rounding) self.group_layout.addWidget(perhitungan_widget) self._widget_list.append(perhitungan_widget) # hapus widget yang ditunjuk obj def remove_widget(self, obj): self.group_layout.removeWidget(obj) obj.hide() obj.destroy() def set_rounding(self, val): self._rounding = val for item in self._widget_list: item.set_rounding(val) # hapus widget paling akhir def pop_widget(self): if self._widget_list: perhitungan_widget = self._widget_list.pop() self.remove_widget(perhitungan_widget) # hapus semua widget def clear_widget(self): # ulangi sampai _widget_list kosong while self._widget_list: self.pop_widget() # clear semua nilai def clear_value(self): for item in self._widget_list: item.clear_value()
class ConfigListWidget(QWidget): def __init__(self, parent=None, flags=Qt.WindowFlags()): super().__init__(parent=parent, flags=flags) self.idSegmentConfigWidgetMap = {} self.mainLayout = QVBoxLayout() self.mainLayout.setAlignment(Qt.AlignTop) self.buttonGroupLayout = QHBoxLayout() self._configButtonGroupLayout() self.segmentConfigListLayout = QVBoxLayout() self.segmentConfigListLayout.setAlignment(Qt.AlignTop) wrapperWidget = QWidget() wrapperWidget.setLayout(self.segmentConfigListLayout) scrollArea = QScrollArea() scrollArea.setWidgetResizable(True) scrollArea.setWidget(wrapperWidget) self.generateButton = QPushButton(QIcon(), "Generate Manipulator") self.generateButton.clicked.connect(lambda: StateManagement().generateSegmentsSrc.on_next(None)) self.mainLayout.addLayout(self.buttonGroupLayout) self.mainLayout.addWidget(scrollArea) self.mainLayout.addWidget(self.generateButton) self.setLayout(self.mainLayout) StateManagement().addSegmentConfigSink.subscribe(on_next=lambda idModelPair: self._addSegmentConfig(idModelPair)) StateManagement().removeSegmentConfigSink.subscribe(on_next=lambda key: self._removeSegmentConfig(key)) def _configButtonGroupLayout(self): addButton = QPushButton("Add Segment Config") addButton.clicked.connect(lambda: StateManagement().addSegmentConfigSrc.on_next(None)) self.buttonGroupLayout.addWidget(addButton) def _addSegmentConfig(self, idModelPair): self.idSegmentConfigWidgetMap[idModelPair[0]] = ConfigWidget(idModelPair) self.segmentConfigListLayout.addWidget(self.idSegmentConfigWidgetMap[idModelPair[0]]) def _removeSegmentConfig(self, val): if isinstance(val, UUID): w = self.idSegmentConfigWidgetMap.get(val) if w: w.setParent(None) self.segmentConfigListLayout.removeWidget(w) del self.idSegmentConfigWidgetMap[val] # elif isinstance(val, (QWidget)): # val.setParent(None) # self.segmentConfigListLayout.removeWidget(val) # else: # removeFromLayout(self.segmentConfigListLayout, -1) def minimumSizeHint(self): return QSize(200,200)
class OuterWidget(QWidget): def __init__(self, callerObject): super(QWidget, self).__init__(callerObject) self.caller = callerObject self.layout = QVBoxLayout(self) self.tabs = QTabWidget() self.tab1 = Form(self) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.tabs.removeTab) self.tab1.refreshRead() self.tabs.addTab(self.tab1, "Home") self.layout.addWidget(self.tabs) self.setLayout(self.layout) #This function is to load a tab for Average of Temperature and Humidity def aver(self): tempAvg = np.mean(listTemperature) humidAvg = np.mean(listHumidity) dateTime = datetime.today() print("listTemperature: ", listTemperature[0:100], "\n") print('Average Temperature: {0:0.1f}'.format(tempAvg)) self.tab2 = Average(self) temper = '{0:0.2f}'.format(tempAvg) + ' C' humid = '{0:0.2f}'.format(humidAvg) + ' %' date = '{:%Y-%m-%d %H:%M}'.format(dateTime) self.tab2.textBrowser.setText(temper) self.tab2.textBrowser_2.setText(humid) self.tab2.textBrowser_3.setText(date) if self.tabs.count() < 2: averageIndex = self.tabs.addTab(self.tab2, "Mean Values") self.tabs.setCurrentIndex(averageIndex) else: self.tabs.setCurrentIndex(1) #This function is used to close this rudimentary thermostat application def closeApp(self): self.tabs.removeTab(1) self.tabs.removeTab(0) self.layout.removeWidget(self.tabs) self.caller.close() #This function is used to close the tab that was opened for Mean Data of temperature and Humidity def closeAvgTab(self): index = self.tabs.currentIndex() self.tabs.removeTab(index)
class GUIEvaluation(QWidget): finished = pyqtSignal() def __init__(self, analysis, eval_window): super(GUIEvaluation, self).__init__() self.eval_window = eval_window self.analysis = analysis self.evaluation = Evaluation(self.analysis) thread = threading.Thread(target=self.evaluation.execute, args=()) thread.start() self.layout = QVBoxLayout(self) self.layout.setSizeConstraint(QLayout.SetNoConstraint) self.layout.setContentsMargins(0, 0, 0, 0) self.view = EvaluationView(self, parent=self) self.layout.addWidget(self.view) self.view.scene.update_states() temp = self.evaluation.final_task self.navigation = EvaluationNavigation(self) self.navigation.add_item(self.evaluation.final_task, self.analysis.name) self.navigation_dock = eval_window.navigation_dock timer = QTimer() timer.start(0.25) timer.timeout.connect(self.view.scene.update_states) self.view.scene.update_states() while thread.is_alive(): QApplication.processEvents() def run(self): self.eval = Evaluation(self.analysis) self.result = self.evaluation.execute() def double_click(self, g_action): task = self.navigation.current_task().childs[g_action.name] if type(task) is Atomic: return self.navigation.add_item(task, g_action.name) self.change_view(task) if not self.navigation_dock.isVisible(): self.navigation_dock.show() def change_view(self, task): self.layout.removeWidget(self.view) self.view = EvaluationView(self, task) self.layout.addWidget(self.view) self.eval_window.data_editor.clear()
class Graph_Func(QWidget): def __init__(self): super().__init__() self.main_layout = QVBoxLayout() self.plt = pg.PlotWidget() self.plt.addLegend(size=(150, 80)) self.plt.showGrid(x=True, y=True, alpha=0.5) self.main_layout.addWidget(self.plt) self.setLayout(self.main_layout) def set_data(self, file_name): self.data = pd.DataFrame(pd.read_csv(file_name)) def plt_show(self, num): self.main_layout.removeWidget(self.plt) self.plt = pg.PlotWidget() self.plt.addLegend(size=(150, 80)) self.plt.showGrid(x=True, y=True, alpha=0.5) for i in num.split(","): i = int(i) self.plt.plot(x=self.data.index.tolist(), y=list(self.data.iloc[:,i]), pen=colour[i-1], name=yp_list[i-1]) self.label = pg.TextItem() # 创建一个文本项 self.plt.addItem(self.label) self.vLine = pg.InfiniteLine(angle=90, movable=False, ) self.hLine = pg.InfiniteLine(angle=0, movable=False, ) self.plt.addItem(self.vLine, ignoreBounds=True) # 在图形部件中添加垂直线条 self.plt.addItem(self.hLine, ignoreBounds=True) # 在图形部件中添加水平线条 self.move_slot = pg.SignalProxy(self.plt.scene().sigMouseMoved, rateLimit=60, slot=self.mouse_moved) self.main_layout.addWidget(self.plt) def mouse_moved(self, event=None): if event is None: print("事件为空") else: pos = event[0] ## using signal proxy turns original arguments into a tuple try: if self.plt.sceneBoundingRect().contains(pos): mousePoint = self.plt.plotItem.vb.mapSceneToView(pos) index = int(mousePoint.x()) #print("坐标:", (index, mousePoint.y()), "值:",(self.data.iloc[:, 0][index])) if 0 < index < len(self.data): self.label.setHtml("<p style='color:white'>频率:{0}</p>" .format(self.data.iloc[:, 0][index].astype(str))) self.label.setPos(mousePoint.x(), mousePoint.y()) self.vLine.setPos(mousePoint.x()) self.hLine.setPos(mousePoint.y()) except Exception as e: print(e)
class Tab(QWidget): layout_inputs = None name = "Novo" amount = 0 inputs = [] parent = None def __init__(self, parent, name, amount): super(Tab, self).__init__() self.name = name self.amount = amount self.parent = parent self.init_ui() def init_ui(self): self.layout_inputs = QVBoxLayout() self.setLayout(self.layout_inputs) for i in range(self.amount): value = QLineEdit() value.textChanged.connect(self.keep_valid) # value.textChanged.connect(self.parent.input_changed) value.setText('0') value.setInputMask('9999999') value.setCursorPosition(0) self.inputs.append(value) self.layout_inputs.addWidget(value) l = QVBoxLayout() l.addSpacing(1) l.addStretch(-1) self.layout_inputs.addLayout(l) def update_tab(self, amount): if amount > self.amount: for i in range(amount - self.amount): value = QLineEdit() value.textChanged.connect(self.keep_valid) # value.textChanged.connect(self.parent.input_changed) value.setText('0') value.setInputMask('9999999') value.setCursorPosition(0) self.inputs.append(value) self.layout_inputs.insertWidget(0, value) else: for i in range(amount, self.amount): self.layout_inputs.removeWidget(self.inputs[-1]) self.inputs[-1].hide() self.inputs[-1].close() self.inputs.remove(self.inputs[-1]) self.amount = amount def keep_valid(self, txt): if txt == "": self.value.setText("0") self.value.setCursorPosition(0)
class MessageView(QWidget): """Widget which stacks error/warning/info messages.""" reposition = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) self._clear_timer = QTimer() self._clear_timer.timeout.connect(self._clear_messages) self._set_clear_timer_interval() objreg.get('config').changed.connect(self._set_clear_timer_interval) self._last_text = None self._messages = [] @config.change_filter('ui', 'message-timeout') def _set_clear_timer_interval(self): """Configure self._clear_timer according to the config.""" self._clear_timer.setInterval(config.get('ui', 'message-timeout')) def message_height(self): """Get the total height of all messages.""" return sum(label.sizeHint().height() for label in self._messages) @pyqtSlot() def _clear_messages(self): """Hide and delete all messages.""" for widget in self._messages: self._vbox.removeWidget(widget) widget.hide() widget.deleteLater() self._messages = [] self._last_text = None self.hide() self._clear_timer.stop() @pyqtSlot(usertypes.MessageLevel, str) def show_message(self, level, text): """Show the given message with the given MessageLevel.""" if text == self._last_text: return widget = Message(level, text, parent=self) self._vbox.addWidget(widget) widget.show() self._clear_timer.start() self._messages.append(widget) self._last_text = text self.show() self.reposition.emit()
class SelectData(QWidget): def __init__(self, HDV): QWidget.__init__(self) self.HDV = HDV self.data_items = list() self._initUI() self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint) def _initUI(self): self.setGeometry(350, 350, 400, 300) self.setWindowTitle('Select Data') # self.setStyleSheet("background-color: gray;") self._make_widgets() self._make_layout() self._make_connect() def closeEvent(self, event): pass def _make_widgets(self): pass def _make_layout(self): self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addStretch() def _make_connect(self): pass # self.dataTree.itemChanged.connect(self.onChangeHandler) def addFolder(self, folder): pass def add_data_handle(self, data_handle): self.data_items.append(DataListItem(data_handle, parent=self)) data_handle.set_data_item(self.data_items[-1]) self.layout.insertWidget(self.layout.count() - 1, self.data_items[-1]) def remove_data_handle(self, data_handle): self.layout.removeWidget(data_handle.data_item) self.data_items.remove(data_handle.data_item) data_handle.data_item.deleteLater()
class MainTab(QWidget): layout = None layout_inputs = None btn_add_input = None btn_remove_input = None name = "Categoria" parent = None all_inputs = [] def __init__(self, parent): super(MainTab, self).__init__() self.parent = parent self.init_ui() def init_ui(self): self.layout = QVBoxLayout() self.btn_remove_input = QPushButton("-") self.btn_remove_input.setStyleSheet(""" background-color: red; color: white; """) self.btn_remove_input.clicked.connect(self.remove_input) self.btn_add_input = QPushButton("+") self.btn_add_input.setStyleSheet(""" background-color: green; color: white; """) self.btn_add_input.clicked.connect(self.add_input) self.layout_inputs = QVBoxLayout() self.layout.addLayout(self.layout_inputs) self.layout.addStretch(-1) self.layout.addWidget(self.btn_remove_input) self.layout.addWidget(self.btn_add_input) self.setLayout(self.layout) def add_input(self): new_inp = MainInput() self.all_inputs.append(new_inp) self.layout_inputs.addWidget(new_inp) self.parent.update_all_tabs(len(self.all_inputs)) def remove_input(self): if len(self.all_inputs) > 1: self.layout_inputs.removeWidget(self.all_inputs[-1]) self.all_inputs[-1].hide() self.all_inputs.remove(self.all_inputs[-1]) self.parent.update_all_tabs(len(self.all_inputs)) def input_changed(self, value): print(value)
class NavigationContainer(QWidget): def __init__(self, parent=None): super(NavigationContainer, self).__init__(parent) self._layout = None # QVBoxLayout self._tabBar = None # TabBar self._layout = QVBoxLayout(self) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self.setLayout(self._layout) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) def addWidget(self, widget): ''' @param: widget QWidget ''' self._layout.addWidget(widget) def setTabBar(self, tabBar): ''' @param: tabBar TabBar ''' self._tabBar = tabBar self._layout.addWidget(self._tabBar) self.toggleTabsOnTop(gVar.qzSettings.tabsOnTop) def toggleTabsOnTop(self, enable): self.setUpdatesEnabled(False) self._layout.removeWidget(self._tabBar) index = 0 if not enable: index = self._layout.count() self._layout.insertWidget(index, self._tabBar) top = enable and 2 or 0 bottom = enable and 2 or 0 self._layout.setContentsMargins(0, top, 0, bottom) self.setUpdatesEnabled(True) # private: # override def paintEvent(self, event): ''' @param: event QPaintEvent ''' super(NavigationContainer, self).paintEvent(event) # Draw line at the bottom of navigation bar if tabs are on top # To visually distinguish navigation bar from the page if gVar.qzSettings.tabsOnTop: p = QPainter(self) lineRect = QRect(0, self.height() - 1, self.width(), 1) color = self.palette().window().color().darker(125) p.fillRect(lineRect, color)
class DownloadPage(QWidget): def __init__(self, parent): super(DownloadPage, self).__init__() self.setMinimumSize(500, 300) self.parent = parent self.nbDownload = 0 self.layoutMain = QVBoxLayout(self) self.scroll = QScrollArea(self) self.scroll.setWidgetResizable(True) self.title = QLabel("Téléchargements") self.title.setAlignment(Qt.AlignHCenter) self.layoutMain.addWidget(self.title) self.layoutMain.addWidget(self.scroll) self.container = QWidget() self.scroll.setWidget(self.container) self.layout = QVBoxLayout(self.container) self.label = QLabel("Pas de téléchargement") self.label.setAlignment(Qt.AlignHCenter) self.layout.addWidget(self.label) def downloadrequested(self, download): if download: if download.state() == QWebEngineDownloadItem.DownloadRequested: path = QFileDialog.getSaveFileName(self, "Sauver comme", download.path()) if path == "": return else: download.setPath(path[0]) download.accept() self.add(DownloadWidget(download, self.parent.parent.browserWidget.url().toString(), self.parent.parent)) self.show() else: QMessageBox.warning(self, "ERREUR", "Le téléchargement n'a pas été demandé.") else: QMessageBox.warning(self, "ERREUR", "Le téléchargement est nul.") def add(self, downloadwidget): downloadwidget.downloadSignal.removeClicked.connect(self.remove) self.layout.addWidget(downloadwidget) self.layout.setAlignment(downloadwidget, Qt.AlignTop) self.nbDownload += 1 if self.nbDownload >= 0: self.label.hide() def remove(self): downloadwidget = self.sender().parent self.layout.removeWidget(downloadwidget) downloadwidget.deleteLater() self.nbDownload -= 1 if self.nbDownload <= 0: self.label.show()
class QScrollableBox(QWidget): def __init__(self, parent): super(QScrollableBox, self).__init__(parent) mainLayout = QVBoxLayout() mainLayout.setContentsMargins(0, 0, 0, 0) self.scrollArea = QScrollArea(self) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) self.scrollArea.setSizePolicy(sizePolicy) self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.scrollArea.setWidgetResizable(True) mainLayout.addWidget(self.scrollArea) self.setLayout(mainLayout) scrollContents = QWidget() self.m_layout = QVBoxLayout() self.m_layout.setContentsMargins(0, 0, 0, 0) self.m_layout.setSizeConstraint(QLayout.SetNoConstraint) scrollContents.setLayout(self.m_layout) self.scrollArea.setWidget(scrollContents) def addWidget(self, w): if not w: return count = self.m_layout.count() if count > 1: self.m_layout.removeItem(self.m_layout.itemAt(count - 1)) self.m_layout.addWidget(w) w.show() self.m_layout.addStretch() self.scrollArea.update() def removeWidget(self, w): self.m_layout.removeWidget(w) self.scrollArea.update() def insertWidget(self, i, w): self.m_layout.insertWidget(i, w) self.scrollArea.update() def clearWidgets(self): item = self.m_layout.takeAt(0) while item != None: item.widget().deleteLater() self.m_layout.removeItem(item) del item self.scrollArea.update() def indexOf(self, w): return self.m_layout.indexOf(w)
class ResizableFramelessContainer(QWidget): """A resizable frameless container ResizableFramelessContainer can be moved and resized by mouse. Call `attach_widget` to attach an inner widget and `detach` to detach the inner widget. NOTE: this is mainly designed for picture in picture mode currently. """ def __init__(self, ): super().__init__(parent=None) self._widget = None self._old_pos = None self._widget = None # setup window layout self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) self._layout = QVBoxLayout(self) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self.setMouseTracking(True) QShortcut(QKeySequence.Cancel, self).activated.connect(self.hide) def attach_widget(self, widget): """set inner widget""" self._widget = widget self._widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self._layout.insertWidget(0, self._widget) def detach(self): self._layout.removeWidget(self._widget) self._widget = None def mousePressEvent(self, e): self._old_pos = e.globalPos() def mouseMoveEvent(self, e): # NOTE: e.button() == Qt.LeftButton don't work on Windows # on Windows, even I drag with LeftButton, the e.button() return 0, # which means no button if self._old_pos is not None: delta = e.globalPos() - self._old_pos self.move(self.x() + delta.x(), self.y() + delta.y()) self._old_pos = e.globalPos() def mouseReleaseEvent(self, e): self._old_pos = None def resizeEvent(self, e): super().resizeEvent(e)
class FinishedCourse(QWidget): def __init__(self, usr=None): super().__init__() self.usr = usr self.initUI() def initUI(self): self.centerLayout = QVBoxLayout(self) self.msg = QLabel(self) self.rownum = 0 self.showtable = None self.setLayout(self.centerLayout) self.createCenterTable(util.finishedCourse(self.usr)) def delCenterTable(self): if self.msg.text() != '': self.centerLayout.removeWidget(self.msg) if self.rownum >= 0 and self.showtable is not None: self.centerLayout.removeWidget(self.showtable) sip.delete(self.showtable) def createCenterTable(self, data): self.delCenterTable() if len(data) == 0: self.msg.setText('对不起, 未查到有关的选修记录') self.msg.setAlignment(Qt.AlignCenter) self.centerLayout.addWidget(self.msg) return None self.rownum = len(data) self.showtable = QTableWidget(self.rownum, 6) self.showtable.setHorizontalHeaderLabels( ['学期', '课程号', '课程名', '教师号', '教师', '上课时间']) for i in range(self.rownum): for j in range(0, 6): self.showtable.setItem(i, j, QtWidgets.QTableWidgetItem(data[i][j])) #设置水平方向表格为自适应的伸缩模式 self.showtable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Stretch) # 将表格变为禁止编辑 self.showtable.setEditTriggers( QtWidgets.QAbstractItemView.NoEditTriggers) # 设置表格整行选中 self.showtable.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectRows) self.centerLayout.addWidget(self.showtable)
class PluginFrame(QFrame): def __init__(self, plugins, highlighted_plugins=None, parent=None): """ :type plugins: list of Plugin :type highlighted_plugins: list of Plugin """ super().__init__(parent) self.ui = Ui_FramePlugins() self.ui.setupUi(self) self.model = PluginListModel(plugins, highlighted_plugins=highlighted_plugins) self.ui.listViewPlugins.setModel(self.model) self.settings_layout = QVBoxLayout() self.ui.groupBoxSettings.setLayout(self.settings_layout) self.create_connects() try: self.restoreGeometry(constants.SETTINGS.value("{}/geometry".format(self.__class__.__name__))) except TypeError: pass def create_connects(self): self.ui.listViewPlugins.selectionModel().selectionChanged.connect(self.on_list_selection_changed) for plugin in self.model.plugins: if hasattr(plugin, "show_proto_sniff_dialog_clicked"): plugin.show_proto_sniff_dialog_clicked.connect(self.parent().parent().show_proto_sniff_dialog) def save_enabled_states(self): for plugin in self.model.plugins: constants.SETTINGS.setValue(plugin.name, plugin.enabled) @pyqtSlot() def on_list_selection_changed(self): i = self.ui.listViewPlugins.currentIndex().row() self.ui.txtEditPluginDescription.setText(self.model.plugins[i].description) if self.settings_layout.count() > 0: widget = self.settings_layout.takeAt(0).widget() self.settings_layout.removeWidget(widget) widget.setParent(None) self.settings_layout.addWidget(self.model.plugins[i].settings_frame)
class Tab(QWidget): def __init__(self, parent): super(Tab, self).__init__() self.parent = parent self.list = [] self.button_add_graph = QPushButton("Add Graph") self.button_add_graph.clicked.connect(partial(self.addGraph)) self.layout = QVBoxLayout() self.layout.addWidget(self.button_add_graph) self.setLayout(self.layout) def addGraph(self): self.parent.readCfg(self.parent.config_path, last=False) self.layout.addWidget(PlotWindow(self)) self.layout.addWidget(self.button_add_graph) def delGraph(self, widget): widget.close() self.layout.removeWidget(widget)
class ContentView(QWidget): """ Represents a generic container for holding views in ACES. """ def __init__(self, parent=None): """ Initializes the ContentView instance. :param parent: The Qt parent of the content view. """ QWidget.__init__(self, parent) self.setObjectName("ContentView") self.content = None self.layout = QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) self.setContentsMargins(0, 0, 0, 0) def get_content(self): """ Retrieves the content of the view. :returns: The widget that was set as the content of the content view. """ return self.content def set_content(self, content): """ Sets the content of the view. :param content: The widget that will be set as the content of the view. """ # remove the existing content if self.content is not None: self.layout.removeWidget(self.content) self.content.setParent(None) # add the new content self.content = content if self.content is not None: self.layout.addWidget(self.content)
class Tab(QWidget): def __init__(self, tabwidget): QWidget.__init__(self) self.tabwidget = tabwidget self.list = [] self.button_add_graph = QPushButton("Add Graph") self.button_add_graph.clicked.connect(partial(self.addGraph)) self.layout = QVBoxLayout() self.layout.addWidget(self.button_add_graph) self.plotWindow = self.addGraph() self.setLayout(self.layout) @property def mainwindow(self): return self.tabwidget.mainwindow def addGraph(self): widget = PlotWindow(self) self.layout.addWidget(widget) self.button_add_graph.hide() return widget def removeGraph(self, widget): widget.close() self.layout.removeWidget(widget) self.button_add_graph.show() def restart(self): for curve in self.plotWindow.curveList: if curve.watcher and not curve.watcher.isActive(): curve.restart() def stop(self): for curve in self.plotWindow.curveList: if curve.watcher and curve.watcher.isActive(): curve.stop()
class ImageView2DDockWidget(QWidget): onDockButtonClicked = pyqtSignal() onMaxButtonClicked = pyqtSignal() onMinButtonClicked = pyqtSignal() def __init__(self, graphicsView): QWidget.__init__(self) self.graphicsView = graphicsView self._isDocked = True self._isMaximized = False self.setContentsMargins(0, 0, 0, 0) self.layout = QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) self.windowForGraphicsView = ImageView2DFloatingWindow() self.windowForGraphicsView.layout = QVBoxLayout() self.windowForGraphicsView.layout.setContentsMargins(0, 0, 0, 0) self.windowForGraphicsView.setLayout(self.windowForGraphicsView.layout) self.windowForGraphicsView.onCloseClick.connect(self.onDockButton) self.addGraphicsView() def connectHud(self): if hasattr(self.graphicsView, "_hud"): self.graphicsView._hud.dockButtonClicked.connect(self.onDockButton) self.graphicsView._hud.maximizeButtonClicked.connect(self.onMaxButton) def onMaxButton(self): if self._isMaximized: self.onMinButtonClicked.emit() self.minimizeView() else: self.onMaxButtonClicked.emit() self.maximizeView() def onDockButton(self): self.onDockButtonClicked.emit() def addGraphicsView(self): self.layout.addWidget(self.graphicsView) def removeGraphicsView(self): self.layout.removeWidget(self.graphicsView) def undockView(self): self._isDocked = False if hasattr(self.graphicsView, "_hud"): self.graphicsView._hud.dockButton.setIcon("dock") self.graphicsView._hud.maxButton.setEnabled(False) self.removeGraphicsView() self.windowForGraphicsView.layout.addWidget(self.graphicsView) self.windowForGraphicsView.showMaximized() # supersize me self.windowForGraphicsView.setWindowTitle("ilastik") self.windowForGraphicsView.raise_() def dockView(self): self._isDocked = True if hasattr(self.graphicsView, "_hud"): self.graphicsView._hud.dockButton.setIcon("undock") self.graphicsView._hud.maxButton.setEnabled(True) self.windowForGraphicsView.layout.removeWidget(self.graphicsView) self.windowForGraphicsView.hide() self.addGraphicsView() def maximizeView(self): self._isMaximized = True if hasattr(self.graphicsView, "_hud"): self.graphicsView._hud.maxButton.setIcon("minimize") def minimizeView(self): self._isMaximized = False if hasattr(self.graphicsView, "_hud"): self.graphicsView._hud.maxButton.setIcon("maximize")
class MainWindow(QWidget): """The main window of qutebrowser. Adds all needed components to a vbox, initializes sub-widgets and connects signals. Attributes: status: The StatusBar widget. tabbed_browser: The TabbedBrowser widget. _downloadview: The DownloadView widget. _vbox: The main QVBoxLayout. _commandrunner: The main CommandRunner instance. """ def __init__(self, geometry=None, parent=None): """Create a new main window. Args: geometry: The geometry to load, as a bytes-object (or None). parent: The parent the window should get. """ super().__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) self._commandrunner = None self.win_id = next(win_id_gen) self.registry = objreg.ObjectRegistry() objreg.window_registry[self.win_id] = self objreg.register('main-window', self, scope='window', window=self.win_id) tab_registry = objreg.ObjectRegistry() objreg.register('tab-registry', tab_registry, scope='window', window=self.win_id) message_bridge = message.MessageBridge(self) objreg.register('message-bridge', message_bridge, scope='window', window=self.win_id) self.setWindowTitle('qutebrowser') self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) log.init.debug("Initializing downloads...") download_manager = downloads.DownloadManager(self.win_id, self) objreg.register('download-manager', download_manager, scope='window', window=self.win_id) self._downloadview = downloadview.DownloadView(self.win_id) self.tabbed_browser = tabbedbrowser.TabbedBrowser(self.win_id) objreg.register('tabbed-browser', self.tabbed_browser, scope='window', window=self.win_id) dispatcher = commands.CommandDispatcher(self.win_id, self.tabbed_browser) objreg.register('command-dispatcher', dispatcher, scope='window', window=self.win_id) self.tabbed_browser.destroyed.connect( functools.partial(objreg.delete, 'command-dispatcher', scope='window', window=self.win_id)) # We need to set an explicit parent for StatusBar because it does some # show/hide magic immediately which would mean it'd show up as a # window. self.status = bar.StatusBar(self.win_id, parent=self) self._add_widgets() self._downloadview.show() self._completion = completionwidget.CompletionView(self.win_id, self) self._commandrunner = runners.CommandRunner(self.win_id) log.init.debug("Initializing modes...") modeman.init(self.win_id, self) if geometry is not None: self._load_geometry(geometry) elif self.win_id == 0: self._load_state_geometry() else: self._set_default_geometry() log.init.debug("Initial main window geometry: {}".format( self.geometry())) self._connect_signals() # When we're here the statusbar might not even really exist yet, so # resizing will fail. Therefore, we use singleShot QTimers to make sure # we defer this until everything else is initialized. QTimer.singleShot(0, self._connect_resize_completion) objreg.get('config').changed.connect(self.on_config_changed) if config.get('ui', 'hide-mouse-cursor'): self.setCursor(Qt.BlankCursor) objreg.get("app").new_window.emit(self) def __repr__(self): return utils.get_repr(self) @pyqtSlot(str, str) def on_config_changed(self, section, option): """Resize the completion if related config options changed.""" if section == 'completion' and option in ('height', 'shrink'): self.resize_completion() elif section == 'ui' and option == 'statusbar-padding': self.resize_completion() elif section == 'ui' and option == 'downloads-position': self._add_widgets() def _add_widgets(self): """Add or readd all widgets to the VBox.""" self._vbox.removeWidget(self.tabbed_browser) self._vbox.removeWidget(self._downloadview) self._vbox.removeWidget(self.status) position = config.get('ui', 'downloads-position') if position == 'top': self._vbox.addWidget(self._downloadview) self._vbox.addWidget(self.tabbed_browser) elif position == 'bottom': self._vbox.addWidget(self.tabbed_browser) self._vbox.addWidget(self._downloadview) else: raise ValueError("Invalid position {}!".format(position)) self._vbox.addWidget(self.status) def _load_state_geometry(self): """Load the geometry from the state file.""" state_config = objreg.get('state-config') try: data = state_config['geometry']['mainwindow'] geom = base64.b64decode(data, validate=True) except KeyError: # First start self._set_default_geometry() except binascii.Error: log.init.exception("Error while reading geometry") self._set_default_geometry() else: self._load_geometry(geom) def _save_geometry(self): """Save the window geometry to the state config.""" state_config = objreg.get('state-config') data = bytes(self.saveGeometry()) geom = base64.b64encode(data).decode('ASCII') state_config['geometry']['mainwindow'] = geom def _load_geometry(self, geom): """Load geometry from a bytes object. If loading fails, loads default geometry. """ log.init.debug("Loading mainwindow from {}".format(geom)) ok = self.restoreGeometry(geom) if not ok: log.init.warning("Error while loading geometry.") self._set_default_geometry() def _connect_resize_completion(self): """Connect the resize_completion signal and resize it once.""" self._completion.resize_completion.connect(self.resize_completion) self.resize_completion() def _set_default_geometry(self): """Set some sensible default geometry.""" self.setGeometry(QRect(50, 50, 800, 600)) def _get_object(self, name): """Get an object for this window in the object registry.""" return objreg.get(name, scope='window', window=self.win_id) def _connect_signals(self): """Connect all mainwindow signals.""" key_config = objreg.get('key-config') status = self._get_object('statusbar') keyparsers = self._get_object('keyparsers') completion_obj = self._get_object('completion') tabs = self._get_object('tabbed-browser') cmd = self._get_object('status-command') message_bridge = self._get_object('message-bridge') mode_manager = self._get_object('mode-manager') prompter = self._get_object('prompter') # misc self.tabbed_browser.close_window.connect(self.close) mode_manager.entered.connect(hints.on_mode_entered) # status bar mode_manager.entered.connect(status.on_mode_entered) mode_manager.left.connect(status.on_mode_left) mode_manager.left.connect(cmd.on_mode_left) mode_manager.left.connect(prompter.on_mode_left) # commands keyparsers[usertypes.KeyMode.normal].keystring_updated.connect( status.keystring.setText) cmd.got_cmd.connect(self._commandrunner.run_safely) cmd.returnPressed.connect(tabs.on_cmd_return_pressed) tabs.got_cmd.connect(self._commandrunner.run_safely) # config for obj in keyparsers.values(): key_config.changed.connect(obj.on_keyconfig_changed) # messages message_bridge.s_error.connect(status.disp_error) message_bridge.s_warning.connect(status.disp_warning) message_bridge.s_info.connect(status.disp_temp_text) message_bridge.s_set_text.connect(status.set_text) message_bridge.s_maybe_reset_text.connect(status.txt.maybe_reset_text) message_bridge.s_set_cmd_text.connect(cmd.set_cmd_text) message_bridge.s_question.connect(prompter.ask_question, Qt.DirectConnection) # statusbar # FIXME some of these probably only should be triggered on mainframe # loadStarted. # https://github.com/The-Compiler/qutebrowser/issues/112 tabs.current_tab_changed.connect(status.prog.on_tab_changed) tabs.cur_progress.connect(status.prog.setValue) tabs.cur_load_finished.connect(status.prog.hide) tabs.cur_load_started.connect(status.prog.on_load_started) tabs.current_tab_changed.connect(status.percentage.on_tab_changed) tabs.cur_scroll_perc_changed.connect(status.percentage.set_perc) tabs.tab_index_changed.connect(status.tabindex.on_tab_index_changed) tabs.current_tab_changed.connect(status.txt.on_tab_changed) tabs.cur_statusbar_message.connect(status.txt.on_statusbar_message) tabs.cur_load_started.connect(status.txt.on_load_started) tabs.current_tab_changed.connect(status.url.on_tab_changed) tabs.cur_url_text_changed.connect(status.url.set_url) tabs.cur_link_hovered.connect(status.url.set_hover_url) tabs.cur_load_status_changed.connect(status.url.on_load_status_changed) # command input / completion mode_manager.left.connect(tabs.on_mode_left) cmd.clear_completion_selection.connect( completion_obj.on_clear_completion_selection) cmd.hide_completion.connect(completion_obj.hide) @pyqtSlot() def resize_completion(self): """Adjust completion according to config.""" if not self._completion.isVisible(): # It doesn't make sense to resize the completion as long as it's # not shown anyways. return # Get the configured height/percentage. confheight = str(config.get('completion', 'height')) if confheight.endswith('%'): perc = int(confheight.rstrip('%')) height = self.height() * perc / 100 else: height = int(confheight) # Shrink to content size if needed and shrinking is enabled if config.get('completion', 'shrink'): contents_height = ( self._completion.viewportSizeHint().height() + self._completion.horizontalScrollBar().sizeHint().height()) if contents_height <= height: height = contents_height else: contents_height = -1 # hpoint now would be the bottom-left edge of the widget if it was on # the top of the main window. topleft_y = self.height() - self.status.height() - height topleft_y = qtutils.check_overflow(topleft_y, 'int', fatal=False) topleft = QPoint(0, topleft_y) bottomright = self.status.geometry().topRight() rect = QRect(topleft, bottomright) log.misc.debug('completion rect: {}'.format(rect)) if rect.isValid(): self._completion.setGeometry(rect) @cmdutils.register(instance='main-window', scope='window') @pyqtSlot() def close(self): """Close the current window. // Extend close() so we can register it as a command. """ super().close() @cmdutils.register(instance='main-window', scope='window') def fullscreen(self): """Toggle fullscreen mode.""" if self.isFullScreen(): self.showNormal() else: self.showFullScreen() def resizeEvent(self, e): """Extend resizewindow's resizeEvent to adjust completion. Args: e: The QResizeEvent """ super().resizeEvent(e) self.resize_completion() self._downloadview.updateGeometry() self.tabbed_browser.tabBar().refresh() def _do_close(self): """Helper function for closeEvent.""" objreg.get('session-manager').save_last_window_session() self._save_geometry() log.destroy.debug("Closing window {}".format(self.win_id)) self.tabbed_browser.shutdown() def closeEvent(self, e): """Override closeEvent to display a confirmation if needed.""" if crashsignal.is_crashing: e.accept() return confirm_quit = config.get('ui', 'confirm-quit') tab_count = self.tabbed_browser.count() download_manager = objreg.get('download-manager', scope='window', window=self.win_id) download_count = download_manager.running_downloads() quit_texts = [] # Ask if multiple-tabs are open if 'multiple-tabs' in confirm_quit and tab_count > 1: quit_texts.append("{} {} open.".format( tab_count, "tab is" if tab_count == 1 else "tabs are")) # Ask if multiple downloads running if 'downloads' in confirm_quit and download_count > 0: quit_texts.append("{} {} running.".format( tab_count, "download is" if tab_count == 1 else "downloads are")) # Process all quit messages that user must confirm if quit_texts or 'always' in confirm_quit: text = '\n'.join(['Really quit?'] + quit_texts) confirmed = message.ask(self.win_id, text, usertypes.PromptMode.yesno, default=True) # Stop asking if the user cancels if not confirmed: log.destroy.debug("Cancelling closing of window {}".format( self.win_id)) e.ignore() return e.accept() self._do_close()
class Radiobutton(vip_base): def cb_initialize_plugin(self): self.event_choice = DEvent('Choice') self.pl_send_new_event_list([self.event_choice]) self.config = self.pl_get_current_config_ref() para_list = [] self.para_texts = DParameter('texts', default=self.config['option_texts']['value']) self.para_values = DParameter('values', default=self.config['option_values']['value']) para_list.append(self.para_texts) para_list.append(self.para_values) self.pl_send_new_parameter_list(para_list) self.central_widget = QWidget() self.option_texts = [] self.option_values = [] self.pre_selected_index = None if isinstance(self.config['selected_index']['value'], str): if self.config['selected_index']['value'] != '': self.pre_selected_index = int(self.config['selected_index']['value']) self.pl_set_widget_for_internal_usage(self.central_widget) self.layout = QVBoxLayout(self.central_widget) self.buttons = [] self.set_option_texts(self.config['option_texts']['value']) self.set_option_values(self.config['option_values']['value']) self.update_widget() return True def set_option_values(self, values): if isinstance(values, str): self.option_values = str.split(values, ',') for i in range(len(self.option_values)): self.option_values[i] = self.option_values[i].lstrip().rstrip() def set_option_texts(self, texts): if isinstance(texts, str): self.option_texts = str.split(texts, ',') for i in range(len(self.option_texts)): self.option_texts[i] = self.option_texts[i].lstrip().rstrip() def update_widget(self): for button in self.buttons: self.layout.removeWidget(button) button.deleteLater() self.buttons = [] for i in range(len(self.option_texts)): button = QRadioButton(self.option_texts[i]) button.released.connect(self.button_released) if i == self.pre_selected_index: button.setChecked(True) self.buttons.append(button) self.layout.addWidget(button) self.central_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.central_widget.customContextMenuRequested.connect(self.show_context_menu) return self.central_widget def show_context_menu(self, pos): gloPos = self.central_widget.mapToGlobal(pos) self.cmenu = self.pl_create_control_context_menu() self.cmenu.exec_(gloPos) def button_released(self): for i in range(len(self.buttons)): if self.buttons[i].isChecked(): self.config['selected_index']['value'] = str(i) if len(self.option_values) == len(self.option_texts): self.pl_emit_event(self.option_values[i], self.event_choice) else: self.pl_emit_event(self.option_texts[i], self.event_choice) def cb_set_parameter(self, parameter_name, parameter_value): if parameter_name == self.para_texts.name: self.config['option_texts']['value'] = parameter_value self.set_option_texts(parameter_value) self.update_widget() if parameter_name == self.para_values.name: self.config['option_values']['value'] = parameter_value self.set_option_values(parameter_value) def cb_plugin_meta_updated(self): pass def cb_get_plugin_configuration(self): config = { 'option_texts': { 'display_text' : 'Displayed Option', 'value': 'Option Text 1, Option Text 2, Option Text 3', 'tooltip': 'This text is seen by the user. Must be separated by commas.', 'advanced' : 'Radiobutton' }, 'option_values': { 'display_text' : 'Value per Option', 'value': '', 'tooltip': 'It is possible to set a value for every option. ' 'The corresponding value is send instead of the displayed text. ', 'advanced' : 'Radiobutton' }, 'selected_index': { 'display_text' : 'Preselected Option', 'value' : '', 'regex' : pc.REGEX_SINGLE_INT, 'tooltip': 'Preselect an option by its index.', 'advanced' : 'Radiobutton' }, 'name': { 'display_text' : 'Plugin Name', 'value': 'RadioButton Label', 'tooltip': 'Used for window title', 'advanced': 'Appearance' }} return config def cb_quit(self): pass def cb_new_parameter_info(self, dparameter_object): if isinstance(dparameter_object, DParameter): value = dparameter_object.value if str(value) in self.option_values: self.pre_selected_index = self.option_values.index(str(value)) self.update_widget()
class Ui(QWidget): def __init__(self, socman): super(Ui, self).__init__() # create objects; self.__ob_vlay_main = QVBoxLayout() self.__ob_widget_menu = MenuUI() self.__ob_widget_add = AddUI(socman) self.__ob_widget_list = ListUI(socman) self.__ob_widget_about = AboutUI() # config; self.setLayout(self.__ob_vlay_main) self.setFixedSize(800,600) self.setWindowTitle("Социлогия: основные понятия и др.") self.__ob_widget_menu.buttonClicked = self.__onMenuClicked self.__ob_widget_add.buttonClicked = self.__onAddClicked self.__ob_widget_list.buttonClicked = self.__onListClicked self.__ob_widget_list.doubleClicked = self.__onDoubleClicked self.__ob_widget_about.buttonClicked = self.__onAboutClicked self.__ob_vlay_main.addWidget(self.__ob_widget_menu) self.__ob_vlay_main.setAlignment(Qt.AlignCenter) self.__ob_vlay_main.setContentsMargins(0, 0, 0, 0) def __onMenuClicked(self, text): if(text == "<p align='center'>Добавить"): self.__ob_widget_menu.hide() self.__ob_vlay_main.removeWidget(self.__ob_widget_menu) self.__ob_vlay_main.addWidget(self.__ob_widget_add) self.__ob_widget_add.show() elif(text == "<p align='center'>Список"): self.__ob_widget_menu.hide() self.__ob_vlay_main.removeWidget(self.__ob_widget_menu) self.__ob_vlay_main.addWidget(self.__ob_widget_list) self.__ob_widget_list.showData() def __onAddClicked(self): self.__ob_widget_add.hide() self.__ob_vlay_main.removeWidget(self.__ob_widget_add) self.__ob_vlay_main.addWidget(self.__ob_widget_menu) self.__ob_widget_menu.show() def __onListClicked(self): self.__ob_widget_list.hide() self.__ob_vlay_main.removeWidget(self.__ob_widget_list) self.__ob_vlay_main.addWidget(self.__ob_widget_menu) self.__ob_widget_menu.show() def __onDoubleClicked(self, item): self.__ob_widget_list.hide() self.__ob_vlay_main.removeWidget(self.__ob_widget_list) self.__ob_vlay_main.addWidget(self.__ob_widget_about) self.__ob_widget_about.showData(item) def __onAboutClicked(self): self.__ob_widget_about.hide() self.__ob_vlay_main.removeWidget(self.__ob_widget_about) self.__ob_vlay_main.addWidget(self.__ob_widget_list) self.__ob_widget_list.showData()
class PlotWindow(QWidget): def __init__(self, tab): super(PlotWindow, self).__init__() self.tab = tab self.allAxes = {} self.curveList = [] self.extraLines = [] self.layout = QHBoxLayout() self.graph_layout = QVBoxLayout() self.gbox_layout = QVBoxLayout() self.tabGBActor = QTabWidget() self.dateplot = DatePlot(self) self.customize = Customize(self) self.button_arrow = self.ButtonArrow() self.button_del_graph = self.ButtonDelete() self.gbox_layout.addWidget(self.dateplot) self.gbox_layout.addWidget(self.customize) self.gbox_layout.addWidget(self.tabGBActor) self.gbox_layout.addWidget(self.button_del_graph) self.layout.addLayout(self.graph_layout) self.layout.addWidget(self.button_arrow) self.layout.addLayout(self.gbox_layout) for widget in [self.dateplot, self.customize, self.tabGBActor]: widget.setMaximumWidth(400) self.setLayout(self.layout) @property def mainwindow(self): return self.tab.mainwindow @property def config(self): return self.dateplot.config @property def axes2curves(self): d = {ax: [] for ax in [None] + list(self.allAxes.values())} for curve in self.curveList: d[curve.getAxes()].append(curve) return d @property def line2Curve(self): return {curve.line: curve for curve in self.curveList} @property def axes2id(self): d = {ax: id for id, ax in self.allAxes.items()} d[None] = None return d def createGraph(self, custom): try: self.graph.close() self.graph_layout.removeWidget(self.graph) self.graph.deleteLater() except AttributeError: pass self.graph = Graph(self, custom) self.graph_layout.insertWidget(0, self.graph) def getAxes(self, newType, i=-1): for i, ax in self.allAxes.items(): try: curve = self.axes2curves[ax][0] if curve.type == newType: return ax except IndexError: return ax if i == 3: raise ValueError('No Axe available') return i + 1 def setAxes(self, allAxes): for idAxes, oldAxes in list(self.allAxes.items()): self.unsetLines(oldAxes, allAxes) self.allAxes.pop(idAxes, None) self.allAxes = allAxes def unsetLines(self, axes, newAxes): while axes.lines: line = axes.lines[0] axes.lines.remove(line) try: curve = self.line2Curve[line] curve.line = False if curve.getAxes() not in newAxes.values(): curve.setAxes(None) except KeyError: pass del line def addCurve(self, curveConf): new_curve = Curve(self, curveConf) axes = self.getAxes(new_curve.type) if isinstance(axes, int): idAxes = axes self.customize.allAxes[idAxes].checkbox.setChecked(2) axes = self.allAxes[idAxes] new_curve.setAxes(axes) self.appendCurve(new_curve) self.graph.plotCurves(new_curve) return new_curve def appendCurve(self, new_curve): self.curveList.append(new_curve) self.customize.appendRow(new_curve) def switchCurve(self, axeId, curve): ax = self.allAxes[axeId] if axeId is not None else None self.graph.switchCurve(ax, curve) def removeCurve(self, curve): self.curveList.remove(curve) self.graph.removeCurve(curve) try: checkbox = curve.checkbox checkbox.setCheckable(True) checkbox.setChecked(0) except RuntimeError: pass # Checkbox could have been already deleted def constructGroupbox(self, config): while self.tabGBActor.count(): widget = self.tabGBActor.widget(0) self.clearLayout(widget.layout()) self.tabGBActor.removeTab(0) widget.close() widget.deleteLater() sortedModule = self.sortCfg(config) for actorname in sorted(sortedModule): config = sortedModule[actorname] if config: t = TabActor(self, config) self.tabGBActor.addTab(t, actorname) def showhideConfig(self, button_arrow): if not self.tabGBActor.isHidden(): self.tabGBActor.hide() self.dateplot.hide() self.customize.hide() self.button_del_graph.hide() button_arrow.setIcon(self.mainwindow.icon_arrow_left) else: self.tabGBActor.show() self.button_del_graph.show() self.dateplot.show() self.customize.show() button_arrow.setIcon(self.mainwindow.icon_arrow_right) def ButtonDelete(self): button = QPushButton('Remove Graph') button.clicked.connect(partial(self.removeGraph, self.layout)) return button def ButtonArrow(self): button_arrow = QPushButton() button_arrow.setIcon(self.mainwindow.icon_arrow_right) button_arrow.clicked.connect(partial(self.showhideConfig, button_arrow)) button_arrow.setStyleSheet('border: 0px') return button_arrow def removeGraph(self, layout): self.clearLayout(layout) self.tab.removeGraph(self) def clearLayout(self, layout): if layout is not None: while layout.count(): item = layout.takeAt(0) widget = item.widget() if widget is not None: widget.deleteLater() else: self.clearLayout(item.layout()) def table2label(self, tablename, mergeAIT=False): for key, label in self.mainwindow.cuArms.items(): if key in tablename: return label if mergeAIT: return 'AIT' else: return tablename.split('__')[0].upper() def sortCfg(self, config): sortedDict = {} for dev in config: label = self.table2label(tablename=dev.tablename, mergeAIT=False) try: sortedDict[label].append(dev) except KeyError: sortedDict[label] = [dev] return sortedDict
class display_widget(QWidget): colors=[] def add_fallback(self): global open_gl_working open_gl_working=False self.tb_rotate.setEnabled(False) self.display=gl_fallback() self.hbox.addWidget(self.display) def __init__(self): QWidget.__init__(self) self.complex_display=False self.hbox=QVBoxLayout() self.gl_cmp=gl_cmp(os.path.join(os.getcwd(),"snapshots")) toolbar=QToolBar() toolbar.setIconSize(QSize(42, 42)) self.tb_rotate = QAction(QIcon(os.path.join(get_image_file_path(),"rotate.png")), _("Rotate"), self) self.tb_rotate.triggered.connect(self.tb_rotate_click) toolbar.addAction(self.tb_rotate) self.tb_rotate.setEnabled(True) self.tb_contact = QAction(QIcon(os.path.join(get_image_file_path(),"contact.png")), _("Contacts"), self) self.tb_contact.triggered.connect(self.callback_contacts) toolbar.addAction(self.tb_contact) self.tb_mesh = QAction(QIcon(os.path.join(get_image_file_path(),"mesh.png")), _("Edit the electrical mesh"), self) self.tb_mesh.triggered.connect(self.callback_edit_mesh) toolbar.addAction(self.tb_mesh) self.tb_config = QAction(QIcon(os.path.join(get_image_file_path(),"cog.png")), _("Configuration"), self) self.tb_config.triggered.connect(self.callback_configure) toolbar.addAction(self.tb_config) self.hbox.addWidget(toolbar) enable_3d=inp_get_token_value(os.path.join(os.getcwd(),"config.inp") , "#gui_config_3d_enabled") if enable_3d==None: enable_3d="True" enable_3d=str2bool(enable_3d) if enable_3d==True: self.display=glWidget(self) self.hbox.addWidget(self.display) self.display.setMinimumSize(800, 600) self.timer=QTimer() self.timer.setSingleShot(True) self.timer.timeout.connect(self.timer_update) self.timer.start(2000) else: self.add_fallback() self.setLayout(self.hbox) self.electrical_mesh=tab_electrical_mesh() self.electrical_mesh.changed.connect(self.recalculate) self.contacts_window=contacts_window() self.contacts_window.changed.connect(self.recalculate) self.gl_cmp.slider.changed.connect(self.recalculate) def tb_rotate_click(self): self.display.start_rotate() def timer_update(self): global open_gl_working open_gl_working=not self.display.failed if open_gl_working==True: print("OpenGL is working") else: print("OpenGL is not working going to fallback") self.hbox.removeWidget(self.display) self.display.deleteLater() self.display = None self.add_fallback() help_window().help_append(["warning.png",_("<big><b>OpenGL warning</b></big><br>It looks as if you don't have working 3D graphics acceleration on your computer. gpvdm will therefore fallback to 2D mode. The model will still be fully functional, but not look quite so nice.")]) def set_selected_layer(self,n): global open_gl_working if open_gl_working==True: self.display.selected_layer=n def recalculate(self): self.display.graph_path=self.gl_cmp.slider.get_file_name() self.display.graph_z_max=self.gl_cmp.slider.z_max self.display.graph_z_min=self.gl_cmp.slider.z_min self.display.recalculate() def update(self): # print("recalculate") self.display.update() def callback_configure(self): if self.gl_cmp.isVisible()==True: self.gl_cmp.hide() else: self.gl_cmp.show() def callback_contacts(self): help_window().help_set_help(["contact.png",_("<big><b>Contacts window</b></big>\nUse this window to change the layout of the contacts on the device")]) if self.contacts_window.isVisible()==True: self.contacts_window.hide() else: self.contacts_window.show() def callback_edit_mesh(self): help_window().help_set_help(["mesh.png",_("<big><b>Mesh editor</b></big>\nUse this window to setup the mesh, the window can also be used to change the dimensionality of the simulation.")]) if self.electrical_mesh.isVisible()==True: self.electrical_mesh.hide() else: self.electrical_mesh.show()
class MainWindow(QWidget): """The main window of qutebrowser. Adds all needed components to a vbox, initializes sub-widgets and connects signals. Attributes: status: The StatusBar widget. tabbed_browser: The TabbedBrowser widget. _downloadview: The DownloadView widget. _vbox: The main QVBoxLayout. _commandrunner: The main CommandRunner instance. _overlays: Widgets shown as overlay for the current webpage. """ def __init__(self, geometry=None, parent=None): """Create a new main window. Args: geometry: The geometry to load, as a bytes-object (or None). parent: The parent the window should get. """ super().__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) self._commandrunner = None self._overlays = [] self.win_id = next(win_id_gen) self.registry = objreg.ObjectRegistry() objreg.window_registry[self.win_id] = self objreg.register('main-window', self, scope='window', window=self.win_id) tab_registry = objreg.ObjectRegistry() objreg.register('tab-registry', tab_registry, scope='window', window=self.win_id) message_bridge = message.MessageBridge(self) objreg.register('message-bridge', message_bridge, scope='window', window=self.win_id) self.setWindowTitle('qutebrowser') self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) self._init_downloadmanager() self._downloadview = downloadview.DownloadView(self.win_id) self.tabbed_browser = tabbedbrowser.TabbedBrowser(self.win_id) objreg.register('tabbed-browser', self.tabbed_browser, scope='window', window=self.win_id) self._init_command_dispatcher() # We need to set an explicit parent for StatusBar because it does some # show/hide magic immediately which would mean it'd show up as a # window. self.status = bar.StatusBar(self.win_id, parent=self) self._add_widgets() self._downloadview.show() self._init_completion() log.init.debug("Initializing modes...") modeman.init(self.win_id, self) self._commandrunner = runners.CommandRunner(self.win_id, partial_match=True) self._keyhint = keyhintwidget.KeyHintView(self.win_id, self) self._add_overlay(self._keyhint, self._keyhint.update_geometry) self._messageview = messageview.MessageView(parent=self) self._add_overlay(self._messageview, self._messageview.update_geometry) self._prompt_container = prompt.PromptContainer(self.win_id, self) self._add_overlay(self._prompt_container, self._prompt_container.update_geometry, centered=True, padding=10) objreg.register('prompt-container', self._prompt_container, scope='window', window=self.win_id) self._prompt_container.hide() if geometry is not None: self._load_geometry(geometry) elif self.win_id == 0: self._load_state_geometry() else: self._set_default_geometry() log.init.debug("Initial main window geometry: {}".format( self.geometry())) self._connect_signals() # When we're here the statusbar might not even really exist yet, so # resizing will fail. Therefore, we use singleShot QTimers to make sure # we defer this until everything else is initialized. QTimer.singleShot(0, self._connect_overlay_signals) objreg.get('config').changed.connect(self.on_config_changed) objreg.get("app").new_window.emit(self) def _add_overlay(self, widget, signal, *, centered=False, padding=0): self._overlays.append((widget, signal, centered, padding)) def _update_overlay_geometries(self): """Update the size/position of all overlays.""" for w, _signal, centered, padding in self._overlays: self._update_overlay_geometry(w, centered, padding) def _update_overlay_geometry(self, widget, centered, padding): """Reposition/resize the given overlay.""" if not widget.isVisible(): return size_hint = widget.sizeHint() if widget.sizePolicy().horizontalPolicy() == QSizePolicy.Expanding: width = self.width() - 2 * padding left = padding else: width = size_hint.width() left = (self.width() - size_hint.width()) / 2 if centered else 0 height_padding = 20 status_position = config.get('ui', 'status-position') if status_position == 'bottom': top = self.height() - self.status.height() - size_hint.height() top = qtutils.check_overflow(top, 'int', fatal=False) topleft = QPoint(left, max(height_padding, top)) bottomright = QPoint(left + width, self.status.geometry().top()) elif status_position == 'top': topleft = QPoint(left, self.status.geometry().bottom()) bottom = self.status.height() + size_hint.height() bottom = qtutils.check_overflow(bottom, 'int', fatal=False) bottomright = QPoint(left + width, min(self.height() - height_padding, bottom)) else: raise ValueError("Invalid position {}!".format(status_position)) rect = QRect(topleft, bottomright) log.misc.debug('new geometry for {!r}: {}'.format(widget, rect)) if rect.isValid(): widget.setGeometry(rect) def _init_downloadmanager(self): log.init.debug("Initializing downloads...") download_manager = downloads.DownloadManager(self.win_id, self) objreg.register('download-manager', download_manager, scope='window', window=self.win_id) download_model = downloads.DownloadModel(download_manager) objreg.register('download-model', download_model, scope='window', window=self.win_id) def _init_completion(self): self._completion = completionwidget.CompletionView(self.win_id, self) cmd = objreg.get('status-command', scope='window', window=self.win_id) completer_obj = completer.Completer(cmd, self.win_id, self._completion) self._completion.selection_changed.connect( completer_obj.on_selection_changed) objreg.register('completion', self._completion, scope='window', window=self.win_id) self._add_overlay(self._completion, self._completion.update_geometry) def _init_command_dispatcher(self): dispatcher = commands.CommandDispatcher(self.win_id, self.tabbed_browser) objreg.register('command-dispatcher', dispatcher, scope='window', window=self.win_id) self.tabbed_browser.destroyed.connect( functools.partial(objreg.delete, 'command-dispatcher', scope='window', window=self.win_id)) def __repr__(self): return utils.get_repr(self) @pyqtSlot(str, str) def on_config_changed(self, section, option): """Resize the completion if related config options changed.""" if section != 'ui': return if option == 'statusbar-padding': self._update_overlay_geometries() elif option == 'downloads-position': self._add_widgets() elif option == 'status-position': self._add_widgets() self._update_overlay_geometries() def _add_widgets(self): """Add or readd all widgets to the VBox.""" self._vbox.removeWidget(self.tabbed_browser) self._vbox.removeWidget(self._downloadview) self._vbox.removeWidget(self.status) downloads_position = config.get('ui', 'downloads-position') status_position = config.get('ui', 'status-position') widgets = [self.tabbed_browser] if downloads_position == 'top': widgets.insert(0, self._downloadview) elif downloads_position == 'bottom': widgets.append(self._downloadview) else: raise ValueError("Invalid position {}!".format(downloads_position)) if status_position == 'top': widgets.insert(0, self.status) elif status_position == 'bottom': widgets.append(self.status) else: raise ValueError("Invalid position {}!".format(status_position)) for widget in widgets: self._vbox.addWidget(widget) def _load_state_geometry(self): """Load the geometry from the state file.""" state_config = objreg.get('state-config') try: data = state_config['geometry']['mainwindow'] geom = base64.b64decode(data, validate=True) except KeyError: # First start self._set_default_geometry() except binascii.Error: log.init.exception("Error while reading geometry") self._set_default_geometry() else: self._load_geometry(geom) def _save_geometry(self): """Save the window geometry to the state config.""" state_config = objreg.get('state-config') data = bytes(self.saveGeometry()) geom = base64.b64encode(data).decode('ASCII') state_config['geometry']['mainwindow'] = geom def _load_geometry(self, geom): """Load geometry from a bytes object. If loading fails, loads default geometry. """ log.init.debug("Loading mainwindow from {!r}".format(geom)) ok = self.restoreGeometry(geom) if not ok: log.init.warning("Error while loading geometry.") self._set_default_geometry() def _connect_overlay_signals(self): """Connect the resize signal and resize everything once.""" for widget, signal, centered, padding in self._overlays: signal.connect( functools.partial(self._update_overlay_geometry, widget, centered, padding)) self._update_overlay_geometry(widget, centered, padding) def _set_default_geometry(self): """Set some sensible default geometry.""" self.setGeometry(QRect(50, 50, 800, 600)) def _get_object(self, name): """Get an object for this window in the object registry.""" return objreg.get(name, scope='window', window=self.win_id) def _connect_signals(self): """Connect all mainwindow signals.""" key_config = objreg.get('key-config') status = self._get_object('statusbar') keyparsers = self._get_object('keyparsers') completion_obj = self._get_object('completion') tabs = self._get_object('tabbed-browser') cmd = self._get_object('status-command') message_bridge = self._get_object('message-bridge') mode_manager = self._get_object('mode-manager') # misc self.tabbed_browser.close_window.connect(self.close) mode_manager.entered.connect(hints.on_mode_entered) # status bar mode_manager.entered.connect(status.on_mode_entered) mode_manager.left.connect(status.on_mode_left) mode_manager.left.connect(cmd.on_mode_left) mode_manager.left.connect(message.global_bridge.mode_left) # commands keyparsers[usertypes.KeyMode.normal].keystring_updated.connect( status.keystring.setText) cmd.got_cmd.connect(self._commandrunner.run_safely) cmd.returnPressed.connect(tabs.on_cmd_return_pressed) # key hint popup for mode, parser in keyparsers.items(): parser.keystring_updated.connect(functools.partial( self._keyhint.update_keyhint, mode.name)) # config for obj in keyparsers.values(): key_config.changed.connect(obj.on_keyconfig_changed) # messages message.global_bridge.show_message.connect( self._messageview.show_message) message_bridge.s_set_text.connect(status.set_text) message_bridge.s_maybe_reset_text.connect(status.txt.maybe_reset_text) # statusbar tabs.current_tab_changed.connect(status.prog.on_tab_changed) tabs.cur_progress.connect(status.prog.setValue) tabs.cur_load_finished.connect(status.prog.hide) tabs.cur_load_started.connect(status.prog.on_load_started) tabs.current_tab_changed.connect(status.percentage.on_tab_changed) tabs.cur_scroll_perc_changed.connect(status.percentage.set_perc) tabs.tab_index_changed.connect(status.tabindex.on_tab_index_changed) tabs.current_tab_changed.connect(status.url.on_tab_changed) tabs.cur_url_changed.connect(status.url.set_url) tabs.cur_link_hovered.connect(status.url.set_hover_url) tabs.cur_load_status_changed.connect(status.url.on_load_status_changed) # command input / completion mode_manager.left.connect(tabs.on_mode_left) cmd.clear_completion_selection.connect( completion_obj.on_clear_completion_selection) cmd.hide_completion.connect(completion_obj.hide) @cmdutils.register(instance='main-window', scope='window') @pyqtSlot() def close(self): """Close the current window. // Extend close() so we can register it as a command. """ super().close() @cmdutils.register(instance='main-window', scope='window') def fullscreen(self): """Toggle fullscreen mode.""" if self.isFullScreen(): self.showNormal() else: self.showFullScreen() def resizeEvent(self, e): """Extend resizewindow's resizeEvent to adjust completion. Args: e: The QResizeEvent """ super().resizeEvent(e) self._update_overlay_geometries() self._downloadview.updateGeometry() self.tabbed_browser.tabBar().refresh() def showEvent(self, e): """Extend showEvent to register us as the last-visible-main-window. Args: e: The QShowEvent """ super().showEvent(e) objreg.register('last-visible-main-window', self, update=True) def _do_close(self): """Helper function for closeEvent.""" try: last_visible = objreg.get('last-visible-main-window') if self is last_visible: objreg.delete('last-visible-main-window') except KeyError: pass objreg.get('session-manager').save_last_window_session() self._save_geometry() log.destroy.debug("Closing window {}".format(self.win_id)) self.tabbed_browser.shutdown() def closeEvent(self, e): """Override closeEvent to display a confirmation if needed.""" if crashsignal.is_crashing: e.accept() return confirm_quit = config.get('ui', 'confirm-quit') tab_count = self.tabbed_browser.count() download_model = objreg.get('download-model', scope='window', window=self.win_id) download_count = download_model.running_downloads() quit_texts = [] # Ask if multiple-tabs are open if 'multiple-tabs' in confirm_quit and tab_count > 1: quit_texts.append("{} {} open.".format( tab_count, "tab is" if tab_count == 1 else "tabs are")) # Ask if multiple downloads running if 'downloads' in confirm_quit and download_count > 0: quit_texts.append("{} {} running.".format( download_count, "download is" if download_count == 1 else "downloads are")) # Process all quit messages that user must confirm if quit_texts or 'always' in confirm_quit: msg = jinja2.Template(""" <ul> {% for text in quit_texts %} <li>{{text}}</li> {% endfor %} </ul> """.strip()).render(quit_texts=quit_texts) confirmed = message.ask('Really quit?', msg, mode=usertypes.PromptMode.yesno, default=True) # Stop asking if the user cancels if not confirmed: log.destroy.debug("Cancelling closing of window {}".format( self.win_id)) e.ignore() return e.accept() self._do_close()
class PreferencesDialogBase(QDialog): def __init__(self, parent, app, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint super().__init__(parent, flags, **kwargs) self.app = app self._setupUi() self.filterHardnessSlider.valueChanged['int'].connect(self.filterHardnessLabel.setNum) self.buttonBox.clicked.connect(self.buttonClicked) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) def _setupScanTypeBox(self, labels): self.scanTypeHLayout = QHBoxLayout() self.scanTypeLabel = QLabel(self) self.scanTypeLabel.setText(tr("Scan Type:")) self.scanTypeLabel.setMinimumSize(QSize(100, 0)) self.scanTypeLabel.setMaximumSize(QSize(100, 16777215)) self.scanTypeHLayout.addWidget(self.scanTypeLabel) self.scanTypeComboBox = QComboBox(self) for label in labels: self.scanTypeComboBox.addItem(label) self.scanTypeHLayout.addWidget(self.scanTypeComboBox) self.widgetsVLayout.addLayout(self.scanTypeHLayout) def _setupFilterHardnessBox(self): self.filterHardnessHLayout = QHBoxLayout() self.filterHardnessLabel = QLabel(self) self.filterHardnessLabel.setText(tr("Filter Hardness:")) self.filterHardnessLabel.setMinimumSize(QSize(0, 0)) self.filterHardnessHLayout.addWidget(self.filterHardnessLabel) self.filterHardnessVLayout = QVBoxLayout() self.filterHardnessVLayout.setSpacing(0) self.filterHardnessHLayoutSub1 = QHBoxLayout() self.filterHardnessHLayoutSub1.setSpacing(12) self.filterHardnessSlider = QSlider(self) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filterHardnessSlider.sizePolicy().hasHeightForWidth()) self.filterHardnessSlider.setSizePolicy(sizePolicy) self.filterHardnessSlider.setMinimum(1) self.filterHardnessSlider.setMaximum(100) self.filterHardnessSlider.setTracking(True) self.filterHardnessSlider.setOrientation(Qt.Horizontal) self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessSlider) self.filterHardnessLabel = QLabel(self) self.filterHardnessLabel.setText("100") self.filterHardnessLabel.setMinimumSize(QSize(21, 0)) self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessLabel) self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub1) self.filterHardnessHLayoutSub2 = QHBoxLayout() self.filterHardnessHLayoutSub2.setContentsMargins(-1, 0, -1, -1) self.moreResultsLabel = QLabel(self) self.moreResultsLabel.setText(tr("More Results")) self.filterHardnessHLayoutSub2.addWidget(self.moreResultsLabel) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.filterHardnessHLayoutSub2.addItem(spacerItem) self.fewerResultsLabel = QLabel(self) self.fewerResultsLabel.setText(tr("Fewer Results")) self.filterHardnessHLayoutSub2.addWidget(self.fewerResultsLabel) self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub2) self.filterHardnessHLayout.addLayout(self.filterHardnessVLayout) def _setupBottomPart(self): # The bottom part of the pref panel is always the same in all editions. self.fontSizeLabel = QLabel(tr("Font size:")) self.fontSizeSpinBox = QSpinBox() self.fontSizeSpinBox.setMinimum(5) self.widgetsVLayout.addLayout(horizontalWrap([self.fontSizeLabel, self.fontSizeSpinBox, None])) self.languageLabel = QLabel(tr("Language:"), self) self.languageComboBox = QComboBox(self) for lang in SUPPORTED_LANGUAGES: self.languageComboBox.addItem(LANGNAMES[lang]) self.widgetsVLayout.addLayout(horizontalWrap([self.languageLabel, self.languageComboBox, None])) self.copyMoveLabel = QLabel(self) self.copyMoveLabel.setText(tr("Copy and Move:")) self.widgetsVLayout.addWidget(self.copyMoveLabel) self.copyMoveDestinationComboBox = QComboBox(self) self.copyMoveDestinationComboBox.addItem(tr("Right in destination")) self.copyMoveDestinationComboBox.addItem(tr("Recreate relative path")) self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path")) self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox) self.customCommandLabel = QLabel(self) self.customCommandLabel.setText(tr("Custom Command (arguments: %d for dupe, %r for ref):")) self.widgetsVLayout.addWidget(self.customCommandLabel) self.customCommandEdit = QLineEdit(self) self.widgetsVLayout.addWidget(self.customCommandEdit) def _setupAddCheckbox(self, name, label, parent=None): if parent is None: parent = self cb = QCheckBox(parent) cb.setText(label) setattr(self, name, cb) def _setupPreferenceWidgets(self): # Edition-specific pass def _setupUi(self): self.setWindowTitle(tr("Preferences")) self.resize(304, 263) self.setSizeGripEnabled(False) self.setModal(True) self.mainVLayout = QVBoxLayout(self) self.widgetsVLayout = QVBoxLayout() self._setupPreferenceWidgets() self.mainVLayout.addLayout(self.widgetsVLayout) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok|QDialogButtonBox.RestoreDefaults) self.mainVLayout.addWidget(self.buttonBox) if (not ISOSX) and (not ISLINUX): self.mainVLayout.removeWidget(self.ignoreHardlinkMatches) self.ignoreHardlinkMatches.setHidden(True) def _load(self, prefs, setchecked): # Edition-specific pass def _save(self, prefs, ischecked): # Edition-specific pass def load(self, prefs=None): if prefs is None: prefs = self.app.prefs self.filterHardnessSlider.setValue(prefs.filter_hardness) self.filterHardnessLabel.setNum(prefs.filter_hardness) setchecked = lambda cb, b: cb.setCheckState(Qt.Checked if b else Qt.Unchecked) setchecked(self.mixFileKindBox, prefs.mix_file_kind) setchecked(self.useRegexpBox, prefs.use_regexp) setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders) setchecked(self.ignoreHardlinkMatches, prefs.ignore_hardlink_matches) setchecked(self.debugModeBox, prefs.debug_mode) self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type) self.customCommandEdit.setText(prefs.custom_command) self.fontSizeSpinBox.setValue(prefs.tableFontSize) try: langindex = SUPPORTED_LANGUAGES.index(self.app.prefs.language) except ValueError: langindex = 0 self.languageComboBox.setCurrentIndex(langindex) self._load(prefs, setchecked) def save(self): prefs = self.app.prefs prefs.filter_hardness = self.filterHardnessSlider.value() ischecked = lambda cb: cb.checkState() == Qt.Checked prefs.mix_file_kind = ischecked(self.mixFileKindBox) prefs.use_regexp = ischecked(self.useRegexpBox) prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox) prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches) prefs.debug_mode = ischecked(self.debugModeBox) prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex() prefs.custom_command = str(self.customCommandEdit.text()) prefs.tableFontSize = self.fontSizeSpinBox.value() lang = SUPPORTED_LANGUAGES[self.languageComboBox.currentIndex()] oldlang = self.app.prefs.language if oldlang not in SUPPORTED_LANGUAGES: oldlang = 'en' if lang != oldlang: QMessageBox.information(self, "", tr("dupeGuru has to restart for language changes to take effect.")) self.app.prefs.language = lang self._save(prefs, ischecked) #--- Events def buttonClicked(self, button): role = self.buttonBox.buttonRole(button) if role == QDialogButtonBox.ResetRole: self.resetToDefaults()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.lastyear = int(time.strftime('%Y', time.localtime(time.time()))) - 1 self.in_parameters = {u'datetime': str(self.lastyear) + u'年', u'target_area': u'绍兴市', u'density_cell': u'10', u'density_class': 10, u'day_cell': u'15', u'day_class': 10, u'out_type': u'tiff'} self.setupUi() def setupUi(self): self.setObjectName("MainWindow") self.setFixedSize(1040, 915) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) icon = QIcon() icon.addPixmap(QPixmap('./resource/weather-thunder.png'),QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.centralwidget = QWidget(self) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) self.centralwidget.setSizePolicy(sizePolicy) self.centralwidget.setObjectName("centralwidget") self.layoutWidget = QWidget(self.centralwidget) self.layoutWidget.setGeometry(QRect(32, 10, 979, 851)) self.layoutWidget.setObjectName("layoutWidget") self.verticalLayout_5 =QVBoxLayout(self.layoutWidget) self.verticalLayout_5.setContentsMargins(0, 0, 0, 0) self.verticalLayout_5.setObjectName("verticalLayout_5") self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") spacerItem = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.datetime_label = QLabel(self.layoutWidget) self.datetime_label.setObjectName("datetime_label") self.horizontalLayout.addWidget(self.datetime_label) self.datetime = QDateEdit(self.layoutWidget) self.datetime.setDateTime(QDateTime(QDate(self.lastyear, 1, 1), QTime(0, 0, 0))) self.datetime.setObjectName("datetime") self.horizontalLayout.addWidget(self.datetime) spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem1) self.target_area_label = QLabel(self.layoutWidget) self.target_area_label.setObjectName("target_area_label") self.horizontalLayout.addWidget(self.target_area_label) self.target_area = QComboBox(self.layoutWidget) self.target_area.setObjectName("target_area") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.target_area.addItem("") self.horizontalLayout.addWidget(self.target_area) spacerItem2 = QSpacerItem(300, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem2) self.verticalLayout_5.addLayout(self.horizontalLayout) self.tabWidget = QTabWidget(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth()) self.tabWidget.setSizePolicy(sizePolicy) self.tabWidget.setObjectName("tabWidget") self.density_tab = QWidget() self.density_tab.setObjectName("density_tab") self.verticalLayout_3 =QVBoxLayout(self.density_tab) self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_2 =QVBoxLayout() self.verticalLayout_2.setObjectName("verticalLayout_2") self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.density_cell_label = QLabel(self.density_tab) self.density_cell_label.setObjectName("density_cell_label") self.horizontalLayout_2.addWidget(self.density_cell_label) self.density_cell = QSpinBox(self.density_tab) self.density_cell.setProperty("value", 10) self.density_cell.setObjectName("density_cell") self.horizontalLayout_2.addWidget(self.density_cell) spacerItem3 = QSpacerItem(40, 0, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem3) self.density_class_label = QLabel(self.density_tab) self.density_class_label.setObjectName("density_class_label") self.horizontalLayout_2.addWidget(self.density_class_label) self.density_class = QSpinBox(self.density_tab) self.density_class.setProperty("value", 10) self.density_class.setObjectName("density_class") self.horizontalLayout_2.addWidget(self.density_class) spacerItem4 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem4) self.density_mxd = QPushButton(self.density_tab) self.density_mxd.setObjectName("density_mxd") self.horizontalLayout_2.addWidget(self.density_mxd) self.verticalLayout_2.addLayout(self.horizontalLayout_2) self.density_view = QGraphicsView(self.density_tab) self.density_view.setObjectName("density_view") self.verticalLayout_2.addWidget(self.density_view) self.verticalLayout_3.addLayout(self.verticalLayout_2) self.tabWidget.addTab(self.density_tab, "") self.day_tab = QWidget() self.day_tab.setObjectName("day_tab") self.verticalLayout_4 =QVBoxLayout(self.day_tab) self.verticalLayout_4.setObjectName("verticalLayout_4") self.verticalLayout =QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout_3 =QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.day_cell_label = QLabel(self.day_tab) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.day_cell_label.sizePolicy().hasHeightForWidth()) self.day_cell_label.setSizePolicy(sizePolicy) self.day_cell_label.setObjectName("day_cell_label") self.horizontalLayout_3.addWidget(self.day_cell_label) self.day_cell = QSpinBox(self.day_tab) self.day_cell.setProperty("value", 15) self.day_cell.setObjectName("day_cell") self.horizontalLayout_3.addWidget(self.day_cell) spacerItem5 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem5) self.day_class_label = QLabel(self.day_tab) self.day_class_label.setObjectName("day_class_label") self.horizontalLayout_3.addWidget(self.day_class_label) self.day_class = QSpinBox(self.day_tab) self.day_class.setProperty("value", 10) self.day_class.setObjectName("day_class") self.horizontalLayout_3.addWidget(self.day_class) spacerItem6 = QSpacerItem(478, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem6) self.day_mxd = QPushButton(self.day_tab) self.day_mxd.setObjectName("day_mxd") self.horizontalLayout_3.addWidget(self.day_mxd) self.verticalLayout.addLayout(self.horizontalLayout_3) self.day_view = QGraphicsView(self.day_tab) self.day_view.setObjectName("day_view") self.verticalLayout.addWidget(self.day_view) self.verticalLayout_4.addLayout(self.verticalLayout) self.tabWidget.addTab(self.day_tab, "") self.verticalLayout_5.addWidget(self.tabWidget) self.horizontalLayout_4 =QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") self.progressBar = QProgressBar(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.progressBar.sizePolicy().hasHeightForWidth()) self.progressBar.setSizePolicy(sizePolicy) self.progressBar.setProperty("value", 0) self.progressBar.setObjectName("progressBar") self.horizontalLayout_4.addWidget(self.progressBar) self.execute_button = QPushButton(self.layoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.execute_button.sizePolicy().hasHeightForWidth()) self.execute_button.setSizePolicy(sizePolicy) self.execute_button.setObjectName("execute_button") self.horizontalLayout_4.addWidget(self.execute_button) self.verticalLayout_5.addLayout(self.horizontalLayout_4) self.setCentralWidget(self.centralwidget) self.menubar = QMenuBar(self) self.menubar.setGeometry(QRect(0, 0, 1040, 26)) self.menubar.setObjectName("menubar") self.file_menu = QMenu(self.menubar) self.file_menu.setObjectName("file_menu") self.help_menu = QMenu(self.menubar) self.help_menu.setObjectName("help_menu") self.setMenuBar(self.menubar) self.statusbar = QStatusBar(self) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.action_add_data = QAction(self) self.action_add_data.setObjectName("action_add_data") self.action_help = QAction(self) self.action_help.setObjectName("action_help") self.action_about = QAction(self) self.action_about.setObjectName("action_about") self.action_save_pic = QAction(self) self.action_save_pic.setObjectName("action_save_pic") self.file_menu.addAction(self.action_add_data) self.file_menu.addAction(self.action_save_pic) self.help_menu.addAction(self.action_help) self.help_menu.addAction(self.action_about) self.menubar.addAction(self.file_menu.menuAction()) self.menubar.addAction(self.help_menu.menuAction()) self.retranslateUi() self.tabWidget.setCurrentIndex(0) QMetaObject.connectSlotsByName(self) self.center() self.show() self.target_area.activated[str].connect(self.updateTargetArea) self.datetime.dateChanged.connect(self.updateDatetime) self.density_cell.valueChanged.connect(self.updateDensityCell) self.density_class.valueChanged.connect(self.updateDensityClass) self.day_cell.valueChanged.connect(self.updateDayCell) self.day_class.valueChanged.connect(self.updateDayClass) self.action_add_data.triggered.connect(self.addData) self.action_save_pic.triggered.connect(self.savePic) self.action_about.triggered.connect(self.showAbout) self.action_help.triggered.connect(self.showHelp) self.execute_button.clicked.connect(self.execute) self.density_mxd.clicked.connect(self.openMxdDensity) self.day_mxd.clicked.connect(self.openMxdDay) self.density_mxd.setDisabled(True) self.day_mxd.setDisabled(True) self.action_save_pic.setDisabled(True) def execute(self): dir = u"E:/Documents/工作/雷电公报/闪电定位原始文本数据/" + self.in_parameters[u'datetime'] if os.path.exists(dir): datafiles = os.listdir(dir) datafiles = map(lambda x:os.path.join(dir,x),datafiles) self.in_parameters[u'origin_data_path'] = datafiles if not self.in_parameters.has_key(u'origin_data_path'): message = u"请加载%s的数据" % self.in_parameters[u'datetime'] msgBox = QMessageBox() msgBox.setText(message) msgBox.setIcon(QMessageBox.Information) icon = QIcon() icon.addPixmap(QPixmap('./resource/weather-thunder.png'), QIcon.Normal, QIcon.Off) msgBox.setWindowIcon(icon) msgBox.setWindowTitle(" ") msgBox.exec_() return self.execute_button.setDisabled(True) self.execute_button.setText(u'正在制图中……') self.progressBar.setMaximum(0) self.progressBar.setMinimum(0) self.action_add_data.setDisabled(True) self.target_area.setDisabled(True) self.datetime.setDisabled(True) self.density_cell.setDisabled(True) self.density_class.setDisabled(True) self.day_cell.setDisabled(True) self.day_class.setDisabled(True) # for outfile in self.in_parameters[u'origin_data_path']: # infile = # try: # with open(infile, 'w+') as in_f: # for line in in_f: # line = line.replace(u":",":") # in_f.write(line) # except Exception,inst: # print infile self.process_thread = WorkThread() self.process_thread.trigger.connect(self.finished) self.process_thread.beginRun(self.in_parameters) def finished(self): #绘制闪电密度图 ##清除上一次的QGraphicsView对象,防止其记录上一次图片结果,影响显示效果 self.density_view.setAttribute(Qt.WA_DeleteOnClose) self.verticalLayout_2.removeWidget(self.density_view) size = self.density_view.size() self.density_view.close() self.density_view = QGraphicsView(self.density_tab) self.density_view.setObjectName("density_view") self.density_view.resize(size) self.verticalLayout_2.addWidget(self.density_view) densityPic = ''.join([cwd,u'/bulletinTemp/', self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'闪电密度空间分布.tif']) scene = QGraphicsScene() pixmap_density = QPixmap(densityPic) scene.addPixmap(pixmap_density) self.density_view.setScene(scene) scale = float(self.density_view.width()) / pixmap_density.width() self.density_view.scale(scale, scale) #绘制雷暴日图 self.day_view.setAttribute(Qt.WA_DeleteOnClose) self.verticalLayout.removeWidget(self.day_view) size = self.day_view.size() self.day_view.close() self.day_view = QGraphicsView(self.day_tab) self.day_view.setObjectName("day_view") self.day_view.resize(size) self.verticalLayout.addWidget(self.day_view) dayPic = ''.join([cwd,u'/bulletinTemp/', self.in_parameters[u'datetime'],u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif']) pixmap_day = QPixmap(dayPic) scene = QGraphicsScene() scene.addPixmap(pixmap_day) self.day_view.resize(self.density_view.width(),self.density_view.height()) self.day_view.setScene(scene) scale = float(self.day_view.width()) / pixmap_day.width() self.day_view.scale(scale, scale) #处理进度条和执行按钮状态 self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.progressBar.setValue(100) self.progressBar.setFormat(u'完成!') self.execute_button.setDisabled(False) self.execute_button.setText(u'执行') #改变一些控件的状态 self.action_add_data.setDisabled(False) self.target_area.setDisabled(False) self.datetime.setDisabled(False) self.density_cell.setDisabled(False) self.density_class.setDisabled(False) self.day_cell.setDisabled(False) self.day_class.setDisabled(False) self.density_mxd.setDisabled(False) self.day_mxd.setDisabled(False) self.action_save_pic.setDisabled(False) def addData(self): fnames = QFileDialog.getOpenFileNames(self, u'请选择原始的电闪数据', u'E:/Documents/工作/雷电公报/闪电定位原始文本数据', 'Text files (*.txt);;All(*.*)') self.in_parameters[u'origin_data_path'] = fnames[0] def savePic(self): densityPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/', self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'闪电密度空间分布.tif']) dayPic = ''.join([cwd,u'/bulletinTemp/',self.in_parameters[u'datetime'],u'/', self.in_parameters[u'target_area'],'.gdb',u'/',self.in_parameters[u'datetime'], self.in_parameters[u'target_area'],u'地闪雷暴日空间分布.tif']) directory = QFileDialog.getExistingDirectory(self,u'请选择图片保存位置', u'E:/Documents/工作/雷电公报', QFileDialog.ShowDirsOnly|QFileDialog.DontResolveSymlinks) dest_density = os.path.join(directory,os.path.basename(densityPic)) dest_day = os.path.join(directory,os.path.basename(dayPic)) if os.path.isfile(dest_day) or os.path.isfile(dest_density): message = u"文件已经存在!" msgBox = QMessageBox() msgBox.setText(message) msgBox.setIcon(QMessageBox.Information) icon = QIcon() icon.addPixmap(QPixmap("./resource/weather-thunder.png"), QIcon.Normal, QIcon.Off) msgBox.setWindowIcon(icon) msgBox.setWindowTitle(" ") msgBox.exec_() return move(dayPic,directory) move(densityPic,directory) def openMxdDay(self): program = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe' src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb']) dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']]) src_file = ''.join([self.in_parameters[u'target_area'] , u"地闪雷暴日空间分布模板.mxd"]) copy(os.path.join(src_dir,src_file),dest_dir) arguments = [os.path.join(dest_dir,src_file)] self.process = QProcess(self) self.process.start(program,arguments) def openMxdDensity(self): program = u'C:/Program Files (x86)/ArcGIS/Desktop10.3/bin/ArcMap.exe' src_dir = ''.join([cwd,u'/data/LightningBulletin.gdb']) dest_dir = ''.join([cwd,u"/bulletinTemp/",self.in_parameters[u'datetime'], u"/" , self.in_parameters[u'target_area']]) src_file = ''.join([self.in_parameters[u'target_area'] ,u"闪电密度空间分布模板.mxd"]) copy(os.path.join(src_dir,src_file),dest_dir) arguments = [os.path.join(dest_dir,src_file)] self.process = QProcess(self) self.process.start(program,arguments) def showAbout(self): self.about = About_Dialog() def showHelp(self): program = u'C:/Windows/hh.exe' arguments = [''.join([cwd,'/help/help.CHM'])] self.process = QProcess(self) self.process.start(program,arguments) def updateTargetArea(self, area): self.in_parameters[u'target_area'] = area def updateDatetime(self, date): self.in_parameters[u'datetime'] = str(date.year()) + u'年' if self.in_parameters.has_key(u'origin_data_path'): self.in_parameters.__delitem__(u'origin_data_path') def updateDensityCell(self, cell): self.in_parameters[u'density_cell'] = str(cell) def updateDensityClass(self, nclass): self.in_parameters[u'density_class'] = nclass def updateDayCell(self, cell): self.in_parameters[u'day_cell'] = str(cell) def updateDayClass(self, nclass): self.in_parameters[u'day_class'] = nclass def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def retranslateUi(self): _translate = QCoreApplication.translate self.setWindowTitle(_translate("MainWindow", "绍兴防雷中心 雷电公报制图")) self.datetime_label.setText(_translate("MainWindow", "年份")) self.datetime.setDisplayFormat(_translate("MainWindow", "yyyy")) self.target_area_label.setText(_translate("MainWindow", "地区")) self.target_area.setItemText(0, _translate("MainWindow", "绍兴市")) self.target_area.setItemText(1, _translate("MainWindow", "柯桥区")) self.target_area.setItemText(2, _translate("MainWindow", "上虞区")) self.target_area.setItemText(3, _translate("MainWindow", "诸暨市")) self.target_area.setItemText(4, _translate("MainWindow", "嵊州市")) self.target_area.setItemText(5, _translate("MainWindow", "新昌县")) self.density_cell_label.setText(_translate("MainWindow", "插值网格大小")) self.density_class_label.setText(_translate("MainWindow", "制图分类数目")) self.density_mxd.setText(_translate("MainWindow", "ArcGIS文档")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.density_tab), _translate("MainWindow", "电闪密度")) self.day_cell_label.setText(_translate("MainWindow", "插值网格大小")) self.day_class_label.setText(_translate("MainWindow", "制图分类数目")) self.day_mxd.setText(_translate("MainWindow", "ArcGIS文档")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.day_tab), _translate("MainWindow", "雷暴日")) self.execute_button.setText(_translate("MainWindow", "执行")) self.file_menu.setTitle(_translate("MainWindow", "文件")) self.help_menu.setTitle(_translate("MainWindow", "帮助")) self.action_add_data.setText(_translate("MainWindow", "加载数据")) self.action_help.setText(_translate("MainWindow", "使用说明")) self.action_about.setText(_translate("MainWindow", "关于")) self.action_save_pic.setText(_translate("MainWindow", "图片另存为"))
class Radiobutton(vip_base): def cb_initialize_plugin(self): self.event_choice = DEvent("Choice") self.pl_send_new_event_list([self.event_choice]) self.config = self.pl_get_current_config_ref() para_list = [] self.para_texts = DParameter("texts", default=self.config["option_texts"]["value"]) self.para_values = DParameter("values", default=self.config["option_values"]["value"]) para_list.append(self.para_texts) para_list.append(self.para_values) self.pl_send_new_parameter_list(para_list) self.central_widget = QWidget() self.option_texts = [] self.option_values = [] self.pre_selected_index = None if isinstance(self.config["selected_index"]["value"], str): if self.config["selected_index"]["value"] != "": self.pre_selected_index = int(self.config["selected_index"]["value"]) self.pl_set_widget_for_internal_usage(self.central_widget) self.layout = QVBoxLayout(self.central_widget) self.buttons = [] self.set_option_texts(self.config["option_texts"]["value"]) self.set_option_values(self.config["option_values"]["value"]) self.update_widget() return True def set_option_values(self, values): if isinstance(values, str): self.option_values = str.split(values, ",") for i in range(len(self.option_values)): self.option_values[i] = self.option_values[i].lstrip().rstrip() def set_option_texts(self, texts): if isinstance(texts, str): self.option_texts = str.split(texts, ",") for i in range(len(self.option_texts)): self.option_texts[i] = self.option_texts[i].lstrip().rstrip() def update_widget(self): for button in self.buttons: self.layout.removeWidget(button) button.deleteLater() self.buttons = [] for i in range(len(self.option_texts)): button = QRadioButton(self.option_texts[i]) button.released.connect(self.button_released) if i == self.pre_selected_index: button.setChecked(True) self.buttons.append(button) self.layout.addWidget(button) self.central_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.central_widget.customContextMenuRequested.connect(self.show_context_menu) return self.central_widget def show_context_menu(self, pos): gloPos = self.central_widget.mapToGlobal(pos) self.cmenu = self.pl_create_control_context_menu() self.cmenu.exec_(gloPos) def button_released(self): for i in range(len(self.buttons)): if self.buttons[i].isChecked(): self.config["selected_index"]["value"] = str(i) if len(self.option_values) == len(self.option_texts): self.pl_emit_event(self.option_values[i], self.event_choice) else: self.pl_emit_event(self.option_texts[i], self.event_choice) def cb_set_parameter(self, parameter_name, parameter_value): if parameter_name == self.para_texts.name: self.config["option_texts"]["value"] = parameter_value self.set_option_texts(parameter_value) self.update_widget() if parameter_name == self.para_values.name: self.config["option_values"]["value"] = parameter_value self.set_option_values(parameter_value) def cb_plugin_meta_updated(self): pass def cb_get_plugin_configuration(self): config = { "option_texts": { "display_text": "Displayed Option", "value": "Option Text 1, Option Text 2, Option Text 3", "tooltip": "This text is seen by the user. Must be separated by commas.", }, "option_values": { "display_text": "Value per Option", "value": "", "tooltip": "It is possible to set a value for every option. " "The corresponding value is send instead of the displayed text. ", }, "selected_index": { "display_text": "Preselected Option", "value": "", "regex": pc.REGEX_SINGLE_INT, "tooltip": "Preselect an option by its index.", "advanced": "1", }, "name": {"display_text": "Plugin Name", "value": "RadioButton Label", "tooltip": "Used for window title"}, } return config def cb_quit(self): pass def cb_new_parameter_info(self, dparameter_object): if isinstance(dparameter_object, DParameter): value = dparameter_object.default if str(value) in self.option_values: self.pre_selected_index = self.option_values.index(str(value)) self.update_widget()
class PlotContainerWidget(QDockWidget): def __init__(self, parent, plot_area_class, active_data_types): super(PlotContainerWidget, self).__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) # This is required to stop background timers! self.on_close = lambda: None self._plot_area = plot_area_class(self, display_measurements=self.setWindowTitle) self.update = self._plot_area.update self.reset = self._plot_area.reset self._active_data_types = active_data_types self._extractors = [] self._new_extractor_button = make_icon_button('plus', 'Add new value extractor', self, on_clicked=self._do_new_extractor) self._how_to_label = QLabel('\u27F5 Click to configure plotting', self) widget = QWidget(self) layout = QVBoxLayout(widget) layout.addWidget(self._plot_area, 1) footer_layout = QHBoxLayout(self) controls_layout = QVBoxLayout(widget) controls_layout.addWidget(self._new_extractor_button) controls_layout.addStretch(1) controls_layout.setContentsMargins(0, 0, 0, 0) footer_layout.addLayout(controls_layout) footer_layout.addWidget(self._how_to_label) self._extractors_layout = QVBoxLayout(widget) self._extractors_layout.setContentsMargins(0, 0, 0, 0) footer_layout.addLayout(self._extractors_layout, 1) footer_layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(footer_layout) widget.setLayout(layout) self.setWidget(widget) self.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetClosable | QDockWidget.DockWidgetMovable) self.setMinimumWidth(700) self.setMinimumHeight(400) def _do_new_extractor(self): if self._how_to_label is not None: self._how_to_label.hide() self._how_to_label.setParent(None) self._how_to_label.deleteLater() self._how_to_label = None def done(extractor): self._extractors.append(extractor) widget = ExtractorWidget(self, extractor) self._extractors_layout.addWidget(widget) def remove(): self._plot_area.remove_curves_provided_by_extractor(extractor) self._extractors.remove(extractor) self._extractors_layout.removeWidget(widget) widget.on_remove = remove win = NewValueExtractorWindow(self, self._active_data_types) win.on_done = done win.show() def process_transfer(self, timestamp, tr): for extractor in self._extractors: try: value = extractor.try_extract(tr) if value is None: continue self._plot_area.add_value(extractor, timestamp, value) except Exception: extractor.register_error() def closeEvent(self, qcloseevent): super(PlotContainerWidget, self).closeEvent(qcloseevent) self.on_close()
class ClassUI(QWidget): def __init__(self): super().__init__() self.initUI() self.re_1 = re.compile(r"^([A-Z]{2,4})(\d{4})") self.re_2 = re.compile(r"^([A-Z]{2,4})-(\d{4})(\d{2})$") def initUI(self): self.layout = QSplitter() self.in_layout = QVBoxLayout() self.table = QTableWidget() self.headers = ['Class', 'Title', 'Amazon', 'Bookstore', 'Edition', 'ISBN', 'Publisher', 'Author', 'Suggested Retail Price', 'Comments', 'Required'] self.table.setColumnCount(len(self.headers)) self.table.setHorizontalHeaderLabels(self.headers) self.table.cellDoubleClicked.connect(self.tableClicked) self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # self.table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) self.le = [] for i in range(5): self.le.append(QLineEdit(self)) self.table.setRowCount(len(self.le)) #self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.submit_btn = QPushButton('Submit', self) self.submit_btn.clicked.connect(self.submit) self.add_btn = QPushButton('+', self) self.add_btn.clicked.connect(self.add_le) self.rm_btn = QPushButton('-', self) self.rm_btn.clicked.connect(self.rm_le) self.btn_layout = QHBoxLayout() self.in_layout.addWidget(self.submit_btn) self.btn_layout.addWidget(self.add_btn) self.btn_layout.addWidget(self.rm_btn) self.in_layout.addLayout(self.btn_layout) for l in self.le: l.textChanged.connect(self.textChanged) self.in_layout.addWidget(l) self.regex = re.compile("^[A-Z]{2,4}-\d{4}(?:-\d{2})?$") lside = QWidget(self) lside.setLayout(self.in_layout) self.layout.addWidget(lside) self.tab = QTabWidget(self) self.tab.addTab(self.table, 'Books') self.calendar = WeekView() self.tab.addTab(self.calendar, 'Calendar') self.layout.addWidget(self.tab) l = QVBoxLayout() l.addWidget(self.layout) self.setLayout(l) app_icon = QIcon() app_icon.addFile('tulsa.jpg') self.setWindowIcon(app_icon) self.setGeometry(300, 300, 800, 600) self.setWindowTitle('Tulsa class info') self.show() def add_le(self): l = QLineEdit(self) l.textChanged.connect(self.textChanged) self.in_layout.addWidget(l) self.le.append(l) def rm_le(self): l = self.le.pop() self.in_layout.removeWidget(l) l.deleteLater() l = None def textChanged(self): for l in self.le: t = l.text().upper().replace(' ', '-') t = re.sub(self.re_1, r"\1-\2", t) t = re.sub(self.re_2, r"\1-\2-\3", t) l.setText(t) if self.regex.match(l.text()): l.setStyleSheet('color: black') else: l.setStyleSheet('color: red') def tableClicked(self, r, c): if c == 2 or c == 3: cell = self.table.item(r, c) if cell: url = cell.text() if url: QDesktopServices.openUrl(QUrl(url)) def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.close() def set_table_item(self, x, y, s): self.table.setItem(x, y, QTableWidgetItem(s)) def submit(self): data = [l.text() for l in self.le if self.regex.match(l.text())] schedule, times = classes.do_stuff(data) self.calendar.refresh() self.table.clear() self.table.setHorizontalHeaderLabels(self.headers) cur_row = 0 for item in times: for tup in item['times']: self.calendar.add_event(tup[0], tup[1], item['name'], item['building'] + ' ' + item['room']) for key in schedule: for book in schedule[key]: self.table.setRowCount(cur_row + 1) if book['Book Title'] != "No Books Required": result = search.ddg_crawl(search.ddg_search(book['Book Title'] + ' ' + book['ISBN'])) bkstr = search.bookstore_get_url(book['Book Title']) self.set_table_item(cur_row, 2, result) self.set_table_item(cur_row, 3, bkstr) self.set_table_item(cur_row, 0, key) self.set_table_item(cur_row, 1, book['Book Title']) self.set_table_item(cur_row, 4, book['Edition']) self.set_table_item(cur_row, 5, book['ISBN']) self.set_table_item(cur_row, 6, book['Publisher']) self.set_table_item(cur_row, 7, book['Author']) self.set_table_item(cur_row, 8, book['Publishers Suggested Retail Price']) self.set_table_item(cur_row, 9, book['Comments']) self.set_table_item(cur_row, 10, book['Required']) cur_row += 1
class MenuView(QScrollArea): def __init__(self, parent=None, update_func=None, params=None): super().__init__(parent) self.setMaximumWidth(200) self.params = params self.H1_HEIGHT = 50 self.H2_HEIGHT = 50 self.SIDE_MARGIN = 5 self.H1_FONT_SIZE = 18 self.H2_FONT_SIZE = 18 self.H3_FONT_SIZE = 16 self.TEXT_FONT_SIZE = 14 style = ''' QPushButton:flat{ text-align: left; padding: 1ex; } QPushButton:pressed{ background-color: silver; } QPushButton:hover:!pressed{ font: bold; } ''' self.setStyleSheet(style) self.update_func = update_func self.inner = QWidget(self) self.vbox = QVBoxLayout(self.inner) self.vbox.setSpacing(0) self.vbox.setContentsMargins(0, 0, 0, 0) self.vbox.setAlignment(Qt.AlignTop) topframe = QFrame() topframe.setStyleSheet('background-color: white') topframe.setFixedHeight(self.H1_HEIGHT) lbl_h1 = QLabel('Contents', topframe) fnt = lbl_h1.font() fnt.setPointSize(self.H1_FONT_SIZE) lbl_h1.setFont(fnt) lbl_h1.setFixedHeight(self.H1_HEIGHT) lbl_h1.setMargin(self.SIDE_MARGIN) self.vbox.addWidget(topframe) self.list_button = [] if self.params.lang == 'en': self.edit_button('Introduction') else: self.edit_button('はじめに') self.inner.setLayout(self.vbox) self.setWidget(self.inner) def buttonClicked(self, text): if self.update_func is not None: self.update_func(text) def edit_button(self, text, delete=False): if delete: for i in range(self.vbox.count()): widget = self.vbox.itemAt(i).widget() if type(widget) == QPushButton: if widget.text() == '-' + text: self.vbox.removeWidget(widget) widget.deleteLater() widget = None return if text not in self.list_button: self.list_button.append(text) btn = QPushButton('-' + text, self.inner) btn.setFlat(True) fnt = btn.font() fnt.setPointSize(self.TEXT_FONT_SIZE) btn.setFont(fnt) btn.clicked.connect(lambda: self.buttonClicked(text)) self.vbox.addWidget(btn) self.buttonClicked(text)
class FilterBar(QWidget): class Filter(QWidget): def __init__(self, parent, pattern_completion_model): super(FilterBar.Filter, self).__init__(parent) self.on_commit = lambda: None self.on_remove = lambda _: None self._remove_button = make_icon_button('remove', 'Remove this filter', self, on_clicked=lambda: self.on_remove(self)) self._bar = SearchBarComboBox(self, pattern_completion_model) self._bar.on_commit = self._on_commit self._bar.setFocus(Qt.OtherFocusReason) self._apply_button = make_icon_button('check', 'Apply this filter expression [Enter]', self, on_clicked=self._on_commit) self._inverse_button = make_icon_button('random', 'Negate filter', self, checkable=True, on_clicked=self._on_commit) self._regex_button = make_icon_button('code', 'Use regular expressions', self, checkable=True, checked=True, on_clicked=self._on_commit) self._case_sensitive_button = make_icon_button('text-height', 'Filter expression is case sensitive', self, checkable=True, on_clicked=self._on_commit) layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._remove_button) layout.addWidget(self._bar, 1) layout.addWidget(self._apply_button) layout.addWidget(self._inverse_button) layout.addWidget(self._regex_button) layout.addWidget(self._case_sensitive_button) self.setLayout(layout) def _on_commit(self): self._bar.add_current_text_to_history() self.on_commit() def keyPressEvent(self, qkeyevent): super(FilterBar.Filter, self).keyPressEvent(qkeyevent) if qkeyevent.key() == Qt.Key_Escape: self.on_remove(self) def make_matcher(self): matcher = SearchMatcher(self._bar.currentText(), use_regex=self._regex_button.isChecked(), case_sensitive=self._case_sensitive_button.isChecked(), inverse=self._inverse_button.isChecked()) return matcher def __init__(self, parent): super(FilterBar, self).__init__(parent) self.add_filter_button = make_icon_button('filter', 'Add filter', self, on_clicked=self._on_add_filter) self.on_filter = lambda *_: None self._filters = [] self._pattern_completion_model = QStringListModel(self) self._layout = QVBoxLayout(self) self._layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self._layout) self.setVisible(False) def _do_filter(self): if len(self._filters) > 0: chain = SearchMatcherChain() for m in self._filters: chain.append(m.make_matcher()) logger.info('Applying chain of %d filters', len(chain.matchers)) try: self.on_filter(chain) except SearchMatcher.BadPatternException as ex: flash(self, 'Invalid filter pattern: %s' % ex, duration=10) else: self.on_filter(None) def _on_add_filter(self): new_filter = self.Filter(self, self._pattern_completion_model) new_filter.on_remove = self._on_remove_filter new_filter.on_commit = self._do_filter self._filters.append(new_filter) self._layout.addWidget(new_filter) self.setVisible(True) def _on_remove_filter(self, instance): orig_len = len(self._filters) self._filters.remove(instance) assert(orig_len - 1 == len(self._filters)) self._layout.removeWidget(instance) instance.setParent(None) instance.deleteLater() self.setVisible(len(self._filters) > 0) self._do_filter() # Re-applying all remaining filters on removal
class MessageView(QWidget): """Widget which stacks error/warning/info messages.""" update_geometry = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self._messages = [] self._vbox = QVBoxLayout(self) self._vbox.setContentsMargins(0, 0, 0, 0) self._vbox.setSpacing(0) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self._clear_timer = QTimer() self._clear_timer.timeout.connect(self.clear_messages) config.instance.changed.connect(self._set_clear_timer_interval) self._last_text = None def sizeHint(self): """Get the proposed height for the view.""" height = sum(label.sizeHint().height() for label in self._messages) # The width isn't really relevant as we're expanding anyways. return QSize(-1, height) @config.change_filter('messages.timeout') def _set_clear_timer_interval(self): """Configure self._clear_timer according to the config.""" interval = config.val.messages.timeout if interval > 0: interval *= min(5, len(self._messages)) self._clear_timer.setInterval(interval) @pyqtSlot() def clear_messages(self): """Hide and delete all messages.""" for widget in self._messages: self._vbox.removeWidget(widget) widget.hide() widget.deleteLater() self._messages = [] self._last_text = None self.hide() self._clear_timer.stop() @pyqtSlot(usertypes.MessageLevel, str, bool) def show_message(self, level, text, replace=False): """Show the given message with the given MessageLevel.""" if text == self._last_text: return if replace and self._messages and self._messages[-1].replace: old = self._messages.pop() old.hide() widget = Message(level, text, replace=replace, parent=self) self._vbox.addWidget(widget) widget.show() self._messages.append(widget) self._last_text = text self.show() self.update_geometry.emit() if config.val.messages.timeout != 0: self._set_clear_timer_interval() self._clear_timer.start() def mousePressEvent(self, e): """Clear messages when they are clicked on.""" if e.button() in [Qt.LeftButton, Qt.MiddleButton, Qt.RightButton]: self.clear_messages()
class NewGameWidget(Tab): def __init__(self, parent=None): super(NewGameWidget, self).__init__(parent) self.parent = parent self.initUI() def initUI(self): # Setup Layouts self.widgetLayout = QHBoxLayout(self) self.leftColumnLayout = QVBoxLayout() self.rightColumnLayout = QVBoxLayout() self.widgetLayout.addLayout(self.leftColumnLayout) self.widgetLayout.addLayout(self.rightColumnLayout) self.gameStatsBox = None # Players GroupBox self.playersGroupBox = QGroupBox(self) self.rightColumnLayout.addWidget(self.playersGroupBox) self.widgetLayout.setStretchFactor(self.rightColumnLayout, 1) self.populatePlayersGroupBox() # Game GroupBox self.gameGroupBox = QGroupBox(self) self.leftColumnLayout.addWidget(self.gameGroupBox) self.widgetLayout.setStretchFactor(self.leftColumnLayout, 3) self.populateGamesGroupBox() # self.retranslateUI() def retranslateUI(self): self.gameGroupBox.setTitle( i18n("NewGameWidget", "Games")) self.updateGameInfo() self.playersGroupBox.setTitle( i18n("NewGameWidget", "Players")) self.availablePlayersGroup.setTitle( i18n("NewGameWidget", "Available Players")) self.newPlayerButton.setText( i18n("NewGameWidget", "New Player")) self.inGameGroup.setTitle(i18n( "NewGameWidget", "Selected Players")) self.startGameButton.setText( i18n("NewGameWidget", "Play!")) self.resumeGroup.retranslateUI() self.gameStatsBox.retranslateUI() def populateGamesGroupBox(self): self.gameGroupBoxLayout = QVBoxLayout(self.gameGroupBox) self.gameComboBox = QComboBox(self.gameGroupBox) self.gameGroupBoxLayout.addWidget(self.gameComboBox) self.gameDescriptionLabel = QLabel(self.gameGroupBox) self.resumeGroup = ResumeBox(self.parent) self.resumeGroup.restartRequested.connect(self.restartGame) # self.gameRulesBrowser = QTextBrowser(self.gameGroupBox) self.gameGroupBoxLayout.addWidget(self.gameDescriptionLabel) self.gameGroupBoxLayout.addWidget(self.resumeGroup) # self.gameGroupBoxLayout.addWidget(self.gameRulesBrowser) # self.gameGroupBoxLayout.addStretch() self.games = db.getAvailableGames() for game in sorted(self.games.keys()): self.gameComboBox.addItem(game) lastgame = db.getLastGame() if lastgame: self.gameComboBox.setCurrentIndex( self.gameComboBox.findText(lastgame)) self.gameStatsBox = None # self.updateGameInfo() self.gameComboBox.currentIndexChanged.connect(self.updateGameInfo) def updateGameInfo(self, foo=0): game = str(self.gameComboBox.currentText()) description = "2 - {} {}\n\n{}".format( self.games[game]['maxPlayers'], i18n("NewGameWidget", 'players'), self.games[game]['description']) self.gameDescriptionLabel.setText(description) # self.gameRulesBrowser.setText("{}".format(self.games[game]['rules'])) # self.gameStatsBox.update(game) if self.gameStatsBox is not None: self.gameGroupBoxLayout.removeWidget(self.gameStatsBox) # print("UGI deleting") self.gameStatsBox.deleteLater() self.gameStatsBox = QSFactory.createQS(game, None, self) self.gameGroupBoxLayout.addWidget(self.gameStatsBox) self.updateStats() self.resumeGroup.changeGame(game) def updateStats(self): if self.gameStatsBox: try: self.gameStatsBox.update(self.gameComboBox.currentText( ), self.playersInGameList.model().retrievePlayers()) except TypeError: # Should not happen, but silently ignore pass def populatePlayersGroupBox(self): self.playersGroupBoxLayout = QVBoxLayout( self.playersGroupBox) # Start button self.startGameButton = QPushButton(self) self.startGameButton.clicked.connect(self.createNewGame) self.playersGroupBoxLayout.addWidget(self.startGameButton) self.inGameGroup = QGroupBox(self) self.playersGroupBoxLayout.addWidget(self.inGameGroup) self.inGameGroupLayout = QVBoxLayout(self.inGameGroup) self.playersInGameList = PlayerList(None, self.inGameGroup) self.inGameGroup.setMaximumHeight(280) self.inGameGroupLayout.addWidget(self.playersInGameList) self.playersButtonsLayout = QHBoxLayout() self.playersGroupBoxLayout.addLayout(self.playersButtonsLayout) self.newPlayerButton = QPushButton(self.playersGroupBox) self.newPlayerButton.clicked.connect(self.createNewPlayer) self.playersButtonsLayout.addWidget(self.newPlayerButton) self.availablePlayersGroup = QGroupBox(self) self.playersGroupBoxLayout.addWidget(self.availablePlayersGroup) self.availablePlayersGroupLayout = QVBoxLayout( self.availablePlayersGroup) self.playersAvailableList = PlayerList(None, self.playersGroupBox) self.availablePlayersGroupLayout.addWidget(self.playersAvailableList) # self.availablePlayersGroupLayout.addStretch() self.playersAvailableList.doubleclickeditem.connect( self.playersInGameList.addItem) self.playersInGameList.doubleclickeditem.connect( self.playersAvailableList.addItem) self.playersInGameList.changed.connect(self.updateStats) for p in db.getPlayers(): if p['favourite']: self.playersInGameList.addItem(p['nick']) else: self.playersAvailableList.addItem(p['nick']) def createNewGame(self): game = str(self.gameComboBox.currentText()) maxPlayers = self.games[game]['maxPlayers'] players = self.playersInGameList.model().retrievePlayers() tit = i18n("NewGameWidget", "New Match") if len(players) < 2: msg = i18n( "NewGameWidget", "At least 2 players are needed to play") QMessageBox.warning(self, tit, msg) elif len(players) > maxPlayers: msg = i18n("NewGameWidget", 'The maximum number of players is') QMessageBox.warning(self, tit, "{} {}".format(msg, maxPlayers)) else: matchTab = GameWidgetFactory.createGameWidget( game, players, self.parent) if matchTab: matchTab.closeRequested.connect(self.parent.removeTab) matchTab.restartRequested.connect(self.restartGame) self.parent.newTab(matchTab, game) else: QMessageBox.warning(self, tit, i18n("NewGameWidget", "Widget not implemented")) return def restartGame(self, gamewidget): players = gamewidget.players game = gamewidget.game self.parent.removeTab(gamewidget) matchTab = GameWidgetFactory.createGameWidget( game, players, self.parent) if matchTab: matchTab.closeRequested.connect(self.parent.removeTab) matchTab.restartRequested.connect(self.restartGame) self.parent.newTab(matchTab, game) else: QMessageBox.warning(self, tit, i18n("NewGameWidget", "Widget not implemented")) return def createNewPlayer(self): npd = NewPlayerDialog(self) npd.addedNewPlayer.connect(self.addPlayer) npd.exec_() def addPlayer(self, player): player = str(player) self.playersAvailableList.model().addPlayer(player) def showEvent(self, event): if (hasattr(self, 'gameStatsBox') and hasattr(self, 'gameComboBox') and self.gameComboBox.currentText()): self.gameStatsBox.update(self.gameComboBox.currentText()) self.resumeGroup.changeGame(self.gameComboBox.currentText()) return QWidget.showEvent(self, event)
class CollapsibleFrame(QFrame): expanded = pyqtSignal() collapsed = pyqtSignal() def __init__(self, parent: QWidget = None): # Constructs a frame widget with frame style NoFrame and a 1-pixel frame width. super(CollapsibleFrame, self).__init__(parent) # possible values are: # QFrame.NoFrame, QFrame.Box, QFrame.Panel, QFrame.StyledPanel, # QFrame.HLine, QFrame.VLine, QFrame.WinPanel self.setFrameShape(QFrame.StyledPanel) # possible values are: QFrame.Plain, QFrame.Raised, QFrame.Sunken self.setFrameShadow(QFrame.Plain) # layout self._layout = QVBoxLayout() self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self.setLayout(self._layout) # button self._button = QToolButton(self) self._button.setArrowType(Qt.RightArrow) self._button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self._button.setAutoRaise(False) self._button.setText('CollapsibleFrame') self._button.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self._layout.addWidget(self._button, 0) self._button.setVisible(True) # group box self._panel = QWidget(self) self._layout.addWidget(self._panel) self._panel.setVisible(False) self._panel_layout = QVBoxLayout() self._panel_layout.setContentsMargins(1, 1, 1, 1) self._panel_layout.setSpacing(2) self._panel.setLayout(self._panel_layout) # connect signals self._button.clicked.connect(self.on_button_click) # private state variables self._is_collapsed = True def setTitle(self, title: str): self._button.setText(title) def addWidget(self, widget: QWidget): self._panel_layout.addWidget(widget) def removeWidget(self, widget: QWidget): self._panel_layout.removeWidget(widget) def is_expanded(self) -> bool: return not self._is_collapsed def expand(self): self._button.setArrowType(Qt.DownArrow) self._panel.setVisible(True) self._is_collapsed = False self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) def collapse(self): self._panel.setVisible(False) self._button.setArrowType(Qt.RightArrow) self._is_collapsed = True self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) @pyqtSlot() def on_button_click(self): if self._is_collapsed: self.expand() self.expanded.emit() return else: self.collapse() self.collapsed.emit() return