def readSettings(self): self.imageFolder = os.path.normpath(str(self.settings.value("imageFolder").toString())) self.ui.actionIgnore_Transparent_Pixels.setChecked( self.settings.value("ignoreAlpha", True).toBool()) self.ui.actionCheck_for_update_at_start.setChecked( self.settings.value("checkupdate", True).toBool()) self.ui.tolerance_le.setText( self.settings.value("tolerance").toString()) self.settings.beginGroup("/geometry") p = QPoint() # position s = QSize() # size x = self.settings.value("X", -1).toInt()[0] y = self.settings.value("Y", -1).toInt()[0] # don't position outside current screen qRect = QtGui.QDesktopWidget.availableGeometry(app.desktop()) if x > qRect.right(): x = 10 if y > qRect.bottom(): y = 10 p.setX(x) p.setY(y) s.setWidth(self.settings.value("W", -1).toInt()[0]) s.setHeight(self.settings.value("H", -1).toInt()[0]) self.settings.endGroup() if p.x() > 0 and p.y() > 0 and s.width() > 0 and s.height() > 0: self.resize(s) # restore size self.move(p) # restore position
def capture(self, url, output_file, page_size=(1024, 720), img_size=None, post_load_delay=0): self.output_file = output_file self.img_size = img_size self.post_load_delay = post_load_delay if not img_size: img_size = page_size self.img_size = QSize() self.img_size.setWidth(img_size[0]) self.img_size.setHeight(img_size[1]) size = QSize() size.setWidth(page_size[0]) size.setHeight(page_size[1]) self.page().setViewportSize(size) self.load(QUrl(url)) while not self._loaded: self.app.processEvents() time.sleep(0) self._loaded = False
class Screenshot(QWebView): """ Class to grab a screenshot of a web page. Adapted from: http://webscraping.com/blog/Webpage-screenshots-with-webkit/ """ def __init__(self): self.app = QApplication([__file__]) super(Screenshot, self).__init__() self._loaded = False self.loadFinished.connect(self._load_finished) def __del__(self): self.app.exit() def capture(self, url, output_file, page_size=(1024, 720), img_size=None, post_load_delay=0): self.output_file = output_file self.img_size = img_size self.post_load_delay = post_load_delay if not img_size: img_size = page_size self.img_size = QSize() self.img_size.setWidth(img_size[0]) self.img_size.setHeight(img_size[1]) size = QSize() size.setWidth(page_size[0]) size.setHeight(page_size[1]) self.page().setViewportSize(size) self.load(QUrl(url)) while not self._loaded: self.app.processEvents() time.sleep(0) self._loaded = False def _load_finished(self, result): if self.post_load_delay > 0: logger.debug( "Waiting {} seconds for page to run after load".format( self.post_load_delay)) time.sleep(int(self.post_load_delay)) frame = self.page().mainFrame() image = QImage(self.img_size, QImage.Format_ARGB32) painter = QPainter(image) frame.render(painter) painter.end() image.save(self.output_file) self._loaded = True
def sizeHint(self): """ A virtual method implementation which returns the size hint for the layout. """ if self._cached_hint is None: size = QSize(0, 0) for item in self._items: size = size.expandedTo(item.sizeHint()) left, top, right, bottom = self.getContentsMargins() size.setWidth(size.width() + left + right) size.setHeight(size.height() + top + bottom) self._cached_hint = size return self._cached_hint
def sectionSizeFromContents(self, logicalIndex: int) -> QSize: if self._pd.headerModel: curLeafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if curLeafIndex.isValid(): styleOption = QStyleOptionHeader( self.styleOptionForCell(logicalIndex)) s = QSize(self._pd.cellSize(curLeafIndex, self, styleOption)) curLeafIndex = curLeafIndex.parent() while curLeafIndex.isValid(): if self.orientation() == Qt.Horizontal: s.setHeight(s.height() + self._pd.cellSize( curLeafIndex, self, styleOption).height()) else: s.setWidth(s.width() + self._pd.cellSize( curLeafIndex, self, styleOption).width()) curLeafIndex = curLeafIndex.parent() return s return super().sectionSizeFromContents(logicalIndex)
def calculateSize(self, sizeType): totalSize = QSize() for wrapper in self.list: position = wrapper.position itemSize = QSize() if sizeType == self.MinimumSize: itemSize = wrapper.item.minimumSize() else: # sizeType == self.SizeHint itemSize = wrapper.item.sizeHint() if position in (self.North, self.South, self.Center): totalSize.setHeight(totalSize.height() + itemSize.height()) if position in (self.West, self.East, self.Center): totalSize.setWidth(totalSize.width() + itemSize.width()) return totalSize
def minimumSize(self): """ A reimplemented method which returns the minimum size hint of the layout item widget as the minimum size of the window. """ if self._cached_min is None: size = QSize(0, 0) for item in self._items: size = size.expandedTo(item.minimumSize()) left, top, right, bottom = self.getContentsMargins() size.setWidth(size.width() + left + right) size.setHeight(size.height() + top + bottom) self._cached_min = size # XXX hack! We really need hasWidthForHeight! This doesn't quite # work because a QScrollArea internally caches the min size. d = self._options.direction if d == self.TopToBottom or d == self.BottomToTop: m = QSize(self._cached_min) if m.width() < self._cached_wfh: m.setWidth(self._cached_wfh) return m return self._cached_min
def sizeHint(self): """ Get the size hint for the scroll area. This reimplemented method fixes a Qt bug where the size hint is not updated after the scroll widget is first shown. The bug is documented on the Qt bug tracker: https://bugreports.qt-project.org/browse/QTBUG-10545 """ # This code is ported directly from QScrollArea.cpp but instead # of caching the size hint of the scroll widget, it caches the # size hint for the entire scroll area, and invalidates it when # the widget is changed or it receives a LayoutRequest event. hint = self._size_hint if hint.isValid(): return QSize(hint) fw = 2 * self.frameWidth() hint = QSize(fw, fw) font_height = self.fontMetrics().height() widget = self.widget() if widget is not None: if self.widgetResizable(): hint += widget.sizeHint() else: hint += widget.size() else: hint += QSize(12 * font_height, 8 * font_height) if self.verticalScrollBarPolicy() == Qt.ScrollBarAlwaysOn: vbar = self.verticalScrollBar() hint.setWidth(hint.width() + vbar.sizeHint().width()) if self.horizontalScrollBarPolicy() == Qt.ScrollBarAlwaysOn: hbar = self.horizontalScrollBar() hint.setHeight(hint.height() + hbar.sizeHint().height()) hint = hint.boundedTo(QSize(36 * font_height, 24 * font_height)) self._size_hint = hint return QSize(hint)
def sizeHint(self): size = QSize() size.setWidth(self.width * self.fixed_font_width + 2) size.setHeight(self.height * self.fixed_font_height) return size
def sectionSizeFromContents(self, logicalIndex: int)->QSize: if self._pd.headerModel: curLeafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if curLeafIndex.isValid(): styleOption = QStyleOptionHeader(self.styleOptionForCell(logicalIndex)) s = QSize(self._pd.cellSize(curLeafIndex, self, styleOption)) curLeafIndex=curLeafIndex.parent() while curLeafIndex.isValid(): if self.orientation() == Qt.Horizontal: s.setHeight(s.height()+self._pd.cellSize(curLeafIndex, self, styleOption).height()) else: s.setWidth(s.width()+self._pd.cellSize(curLeafIndex, self, styleOption).width()) curLeafIndex=curLeafIndex.parent() return s return super().sectionSizeFromContents(logicalIndex) def paintSection(self, painter: QPainter, rect: QRect, logicalIndex: int): if rect.isValid(): leafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if leafIndex.isValid(): if self.orientation() == Qt.Horizontal: self._pd.paintHorizontalSection(painter, rect, logicalIndex, self, self.styleOptionForCell(logicalIndex), leafIndex) else: self._pd.paintVerticalSection(painter, rect, logicalIndex, self, self.styleOptionForCell(logicalIndex), leafIndex) return super().paintSection(painter, rect, logicalIndex) def on_sectionResized(self, logicalIndex: int): if self.isSectionHidden(logicalIndex): return leafIndex = QModelIndex(self._pd.leafIndex(logicalIndex)) if leafIndex.isValid(): leafsList = QModelIndexList(self._pd.leafs(self._pd.findRootIndex(leafIndex))) for n in range(leafsList.indexOf(leafIndex), 0, -1): logicalIndex-=1 w = self.viewport().width() h = self.viewport().height() pos = self.sectionViewportPosition(logicalIndex) r = QRect(pos, 0, w - pos, h) if self.orientation() == Qt.Horizontal: if self.isRightToLeft(): r.setRect(0, 0, pos + self.sectionSize(logicalIndex), h) else: r.setRect(0, pos, w, h - pos) self.viewport().update(r.normalized()) def setModel(self, model): super().setModel(model) model.layoutChanged.connect(self.layoutChanged) self.layoutChanged() def layoutChanged(self): if self.model(): self._pd.initFromNewModel(self.orientation(), self.model()) axis = ("column", "row")[self.orientation()!=Qt.Horizontal] cnt = getattr(self.model(), axis+"Count")(QModelIndex()) if cnt: self.initializeSections(0, cnt-1) MultiIndexHeaderView=HierarchicalHeaderView class DataFrameModel(QtCore.QAbstractTableModel): #na_values:least|greatest - for sorting options = {"striped": True, "stripesColor": "#fafafa", "na_values": "least", "tooltip_min_len": 21} def __init__(self, dataframe=None): super().__init__() self.setDataFrame(dataframe if dataframe is not None else pd.DataFrame()) def setDataFrame(self, dataframe): self.df = dataframe.copy() # self.df_full = self.df self.layoutChanged.emit() def rowCount(self, parent): return len(self.df) def columnCount(self, parent): return len(self.df.columns) def readLevel(self, y=0, xs=0, xe=None, orient=None): c = getattr(self.df, ("columns", "index")[orient!=HorizontalHeaderDataRole]) if not hasattr(c, "levels"): #not MultiIndex return [QtGui.QStandardItem(str(i)) for i in c] sibl = [] section_start, v, xe = xs, None, xe or len(c) for i in range(xs, xe): label = c.labels[y][i] if label!=v: if y+1<len(c.levels) and i>xs: children = self.readLevel(y+1, section_start, i, orient=orient) sibl[-1].appendRow(children) item = QtGui.QStandardItem(str(c.levels[y][label])) sibl.append(item) section_start = i v=label if y+1<len(c.levels): children = self.readLevel(y+1, section_start, orient=orient) sibl[-1].appendRow(children) return sibl def data(self, index, role): row, col = index.row(), index.column() if role in (Qt.DisplayRole, Qt.ToolTipRole): ret = self.df.iat[row, col] if ret is not None and ret==ret: #convert to str except for None, NaN, NaT if isinstance(ret, float): ret = "{:n}".format(ret) elif isinstance(ret, datetime.date): #FIXME: show microseconds optionally ret = ret.strftime(("%x", "%c")[isinstance(ret, datetime.datetime)]) else: ret = str(ret) if role == Qt.ToolTipRole: if len(ret)<self.options["tooltip_min_len"]: ret = "" return ret elif role == Qt.BackgroundRole: if self.options["striped"] and row%2: return QBrush(QColor(self.options["stripesColor"])) elif role in (HorizontalHeaderDataRole, VerticalHeaderDataRole): hm = QtGui.QStandardItemModel() hm.appendRow(self.readLevel(orient=role)) return hm def reorder(self, oldIndex, newIndex, orientation): "Reorder columns / rows" horizontal = orientation==Qt.Horizontal cols = list(self.df.columns if horizontal else self.df.index) cols.insert(newIndex, cols.pop(oldIndex)) self.df = self.df[cols] if horizontal else self.df.T[cols].T return True # def filter(self, filt=None): # self.df = self.df_full if filt is None else self.df[filt] # self.layoutChanged.emit() def headerData(self, section, orientation, role): if role != Qt.DisplayRole: return label = getattr(self.df, ("columns", "index")[orientation!=Qt.Horizontal])[section] # return label if type(label) is tuple else label return ("\n", " | ")[orientation!=Qt.Horizontal].join(str(i) for i in label) if type(label) is tuple else str(label) def dataFrame(self): return self.df def sort(self, column, order): # print("sort", column, order) #FIXME: double sort after setSortingEnabled(True) if len(self.df): asc = order==Qt.AscendingOrder na_pos = 'first' if (self.options["na_values"]=="least")==asc else 'last' self.df.sort_values(self.df.columns[column], ascending=asc, inplace=True, na_position=na_pos) self.layoutChanged.emit() if __name__=="__main__": import sys, locale locale.setlocale(locale.LC_ALL, '') #system locale settings app = QtGui.QApplication(sys.argv) form = QtGui.QWidget() form.setAttribute(Qt.WA_DeleteOnClose) #http://stackoverflow.com/a/27178019/1119602 form.setMinimumSize(700, 260) view = QtGui.QTableView() QtGui.QVBoxLayout(form).addWidget(view) form.show() #Prepare data tuples=[('bar', 'one', 'q'), ('bar', 'two', 'q'), ('baz', 'one', 'q'), ('baz', 'two', 'q'), ('foo', 'one', 'q'), ('foo', 'two', 'q'), ('qux', 'one', 'q'), ('qux', 'two', 'q')] index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second', 'third']) df=pd.DataFrame(pd.np.random.randn(6, 6), index=index[:6], columns=index[:6]) print("DataFrame:\n%s"%df) #Prepare view # oldh, oldv = view.horizontalHeader(), view.verticalHeader() # oldh.setParent(form), oldv.setParent(form) #Save old headers for some reason MultiIndexHeaderView(Qt.Horizontal, view) MultiIndexHeaderView(Qt.Vertical, view) view.horizontalHeader().setMovable(True) #reorder DataFrame columns manually #Set data view.setModel(DataFrameModel(df)) view.resizeColumnsToContents() view.resizeRowsToContents() #Set sorting enabled (after setting model) view.setSortingEnabled(True) sys.exit(app.exec())
def populate_table(self, content_list, table_id): """ populates the created table with the data :param table_id: int the id of the table to which write the data :param content_list: string data content :return: void """ ref_table = self.tables[table_id] # handles the special case of the start/end list if table_id == 8: l = 1 while l <= len(content_list) - 1: m = 0 while m <= len(content_list[l]) - 1: table_item = QTableWidgetItem( str(content_list[l][m]).replace(",", ""), 0) ref_table.setItem(l, m, table_item) m += 1 l += 1 ref_table.removeRow(0) else: if table_id == 2 and self.include_footpath: self.validation_dk.ui.type3GroupBox.setTitle( str(self.validation_dk.ui.type3GroupBox.title()) + " (including footpaths)") # writes data to columns i = 1 ordered_list = [] while i <= len(content_list) - 1: item_list = str(content_list[i][0]).split('|') ordered_list.append(item_list) i += 1 j = 0 while j <= len(ordered_list) - 1: k = 0 while k <= len(ordered_list[j]) - 1: table_item = QTableWidgetItem(str(ordered_list[j][k]), 0) ref_table.setItem(j, k, table_item) k += 1 j += 1 # resize column widths to content ref_table.resizeColumnsToContents() # hide horizontal header ref_table.verticalHeader().hide() m = 0 columns_sizes = 0 while m <= self.columns_count - 1: header = ref_table.horizontalHeaderItem(m) column_size = ref_table.sizeHintForColumn(m) columns_sizes += column_size m += 1 ref_table.horizontalHeader().setStretchLastSection(True) old_size = QSize() new_size = QSize() old_size.setWidth(ref_table.width()) new_size.setWidth(columns_sizes) resize_event = QResizeEvent(new_size, old_size) ref_table.resizeEvent(resize_event) ref_table_selection_model = ref_table.selectionModel() ref_table.doubleClicked.connect( lambda: self.get_esu_or_usrn(ref_table_selection_model)) ref_table.setToolTip( "Double click on a record to zoom to the feature.")
def __init__( self, ressource_directory, validation_callback: callable, exit_callback: callable, play_callback: callable, screen_id=-1, nb_player=1, nb_life=3, timer_proportions=(0.14, 0.25), life_proportions=(0.12, 0.75), player_proportions=(1, 0.7), player_spacing_proportion=0.33, border_proportion=0.03, multi_life_spacing_proportion=0.12, alpha_color="FF00FF", validate_keys=(65, 32, 16777220, 43), # keys : 'a', space, enter, '+' dev_mode=False): if dev_mode: # TODO utiliser logger print(" Initalisation TwistCanWindow (en mode développeur)") # ----- Init de la fenêtre ----- self.main_app = QApplication(sys.argv) self.main_app.setOverrideCursor(Qt.BlankCursor) # ----- Analyse des paramètres du constructeur ----- # Ajouter le '#' dans les html color if type(alpha_color) == str and len(alpha_color) == 6: alpha_color = "#" + alpha_color self.validate_keys = validate_keys self.validation_callback = validation_callback self.play_callback = play_callback self.exit_callback = exit_callback # récupérer les dimension de l'écran selectioné if screen_id < 0: screen_id = QDesktopWidget().screenCount() screen_size = QDesktopWidget().screenGeometry(screen_id).size() border_size = screen_size.width() * border_proportion timer_size = QSize( round((screen_size.width() - border_size * 2) * timer_proportions[0]), round((screen_size.height() - border_size * 2) * timer_proportions[1])) player_size = QSize( round(screen_size.width() * player_proportions[0]), round(screen_size.height() * player_proportions[1])) life_size = QSize( round( (screen_size.width() - border_size * 2) * life_proportions[0]), round((screen_size.height() - border_size * 2) * life_proportions[1])) # ----- Construction de l'interface ----- # Pose widget if dev_mode: print(" Initialisation Background") self.pose_widget = PoseWidget( ressource_directory, screen_size, player_size, player_spacing_proportion, alpha_color=alpha_color, key_press_event_callback=self.keyPressEventCallback, dev_mode=dev_mode) self.pose_widget.setWindowTitle("TwistCam") # self.setWindowIcon(QtGui.QIcon('web.png')) print("Déplacement du jeu sur l'écran le plus a droite [==>]") # TODO impove avec l'id du screen self.pose_widget.move(QDesktopWidget().width() - 1, 0) self.pose_widget.showFullScreen() # Pose Layout main_layout = QVBoxLayout() main_layout.setSpacing(0) main_layout.setContentsMargins(border_size, border_size, border_size, border_size) self.pose_widget.setLayout(main_layout) # Timer push_right_layout = QBoxLayout(QBoxLayout.RightToLeft) main_layout.addLayout(push_right_layout) self.timer = TimerWidget( ressource_directory, timer_size, dev_mode=dev_mode ) # TODO setup clock_dim and clock_color from config push_right_layout.addWidget(self.timer) push_right_layout.setSpacing(0) push_right_layout.addSpacing(screen_size.width() - 2 * border_size - timer_size.width()) # Lifes if nb_player == 1: # setup special pour 1 seul joueur push_right_layout_2 = QBoxLayout(QBoxLayout.RightToLeft) push_right_layout_2.setSpacing(0) main_layout.addLayout(push_right_layout_2) self.lifes = [ LifeWidget(ressource_directory, life_size, nb_life, dev_mode=dev_mode) ] push_right_layout_2.addWidget(self.lifes[0]) push_right_layout_2.addSpacing(screen_size.width() - 2 * border_size - life_size.width() - (timer_size.width() - life_size.width())) else: multi_life_layout = QHBoxLayout() life_size.setWidth(self.pose_widget.player_pixel_spacing * nb_player) life_offset = (screen_size.width() - 2 * border_size - life_size.width()) * 0.5 multi_life_layout.setContentsMargins(life_offset, 0, life_offset, 0) multi_life_layout.setSpacing( self.pose_widget.player_pixel_spacing * multi_life_spacing_proportion) self.lifes = [ LifeWidget(ressource_directory, QSize( self.pose_widget.player_pixel_spacing * (1 - multi_life_spacing_proportion), life_size.height()), nb_life, dev_mode=dev_mode) for k in range(nb_player) ] for life in self.lifes: multi_life_layout.addWidget(life) main_layout.addSpacing(screen_size.height() - 2 * border_size - timer_size.height() - life_size.height()) main_layout.addLayout(multi_life_layout) # ----- Signaux ----- self.s = self.Signaux(self)
def sizeHint(self): size = QSize() size.setWidth(640) size.setHeight(480) return size
def resizeEvent(self, e): new_grid_size = QSize(self.maximumViewportSize().width(), self.iconSize().height()+self.fontMetrics().height()) if self.verticalScrollBar().isVisible(): new_grid_size.setWidth(new_grid_size.width() - self.verticalScrollBar().width()) self.setGridSize(new_grid_size) return QListView.resizeEvent(self, e)