def draw_spinner(self, painter, rect): width = rect.width() outer_radius = (width - 1) * 0.5 inner_radius = (width - 1) * 0.5 * 0.38 capsule_height = outer_radius - inner_radius capsule_width = int(capsule_height * (0.23 if width > 32 else 0.35)) capsule_radius = capsule_width // 2 painter.save() painter.setRenderHint(painter.Antialiasing) for i in xrange(12): color = QColor(self.color) color.setAlphaF(1.0 - (i / 12.0)) painter.setPen(Qt.NoPen) painter.setBrush(color) painter.save() painter.translate(rect.center()) painter.rotate(self.angle - i * 30.0) painter.drawRoundedRect( -capsule_width * 0.5, -(inner_radius + capsule_height), capsule_width, capsule_height, capsule_radius, capsule_radius, ) painter.restore() painter.restore()
def draw_text(self, style, painter, option, widget, index, item): tr = style.subElementRect(style.SE_ItemViewItemText, option, widget) text = index.data(Qt.DisplayRole) hover = option.state & style.State_MouseOver if hover or gprefs['tag_browser_show_counts']: count = unicode_type(index.data(COUNT_ROLE)) width = painter.fontMetrics().boundingRect(count).width() r = QRect(tr) r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4) painter.drawText(r, Qt.AlignCenter | Qt.TextSingleLine, count) tr.setRight(r.left() - 1) else: tr.setRight(tr.right() - 1) is_rating = item.type == TagTreeItem.TAG and not self.rating_pat.sub('', text) if is_rating: painter.setFont(self.rating_font) flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine lr = QRect(tr) lr.setRight(lr.right() * 2) br = painter.boundingRect(lr, flags, text) if br.width() > tr.width(): g = QLinearGradient(tr.topLeft(), tr.topRight()) c = option.palette.color(QPalette.WindowText) g.setColorAt(0, c), g.setColorAt(0.8, c) c = QColor(c) c.setAlpha(0) g.setColorAt(1, c) pen = QPen() pen.setBrush(QBrush(g)) painter.setPen(pen) painter.drawText(tr, flags, text)
class ColorButton(QToolButton): def __init__(self, color, parent=None): QToolButton.__init__(self, parent) self.setIconSize(QSize(50, 25)) self.pix = QPixmap(self.iconSize()) self._color = QColor('#' + color) self.pix.fill(self._color) self.setIcon(QIcon(self.pix)) self.clicked.connect(self.choose_color) @dynamic_property def color(self): def fget(self): return self._color.name(QColor.HexRgb)[1:] def fset(self, val): self._color = QColor('#' + val) return property(fget=fget, fset=fset) def update_display(self): self.pix.fill(self._color) self.setIcon(QIcon(self.pix)) def choose_color(self): c = QColorDialog.getColor(self._color, self, _('Choose color')) if c.isValid(): self._color = c self.update_display()
def __init__(self, gui): QWidget.__init__(self, gui) self.setObjectName('jobs_pointer') self.setVisible(False) self.resize(100, 80) self.animation = QPropertyAnimation(self, "geometry", self) self.animation.setDuration(750) self.animation.setLoopCount(2) self.animation.setEasingCurve(QEasingCurve.Linear) self.animation.finished.connect(self.hide) taily, heady = 0, 55 self.arrow_path = QPainterPath(QPointF(40, taily)) self.arrow_path.lineTo(40, heady) self.arrow_path.lineTo(20, heady) self.arrow_path.lineTo(50, self.height()) self.arrow_path.lineTo(80, heady) self.arrow_path.lineTo(60, heady) self.arrow_path.lineTo(60, taily) self.arrow_path.closeSubpath() c = self.palette().color(QPalette.Active, QPalette.WindowText) self.color = QColor(c) self.color.setAlpha(100) self.brush = QBrush(self.color, Qt.SolidPattern)
def fset(self, val): val = unicode(val or '') col = QColor(val) orig = self._color if col.isValid(): self._color = val self.setText(val) p = QPixmap(self.iconSize()) p.fill(col) self.setIcon(QIcon(p)) else: self._color = None self.setText(self.choose_text) self.setIcon(QIcon()) if orig != col: self.color_changed.emit(self._color)
def __init__(self, color, parent=None): QToolButton.__init__(self, parent) self.setIconSize(QSize(50, 25)) self.pix = QPixmap(self.iconSize()) self._color = QColor('#' + color) self.pix.fill(self._color) self.setIcon(QIcon(self.pix)) self.clicked.connect(self.choose_color)
def drawSquare(self, painter, x, y, shape): colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC, 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00] color = QColor(colorTable[shape]) painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, self.squareHeight() - 2, color) painter.setPen(color.light()) painter.drawLine(x, y + self.squareHeight() - 1, x, y) painter.drawLine(x, y, x + self.squareWidth() - 1, y) painter.setPen(color.dark()) painter.drawLine(x + 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + self.squareHeight() - 1) painter.drawLine(x + self.squareWidth() - 1, y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1)
def __init__(self, id_i, name,attribs,parent): self.id = id_i self.name = name self.attribs = attribs self.color=QColor(attribs["red"],attribs["green"],attribs["blue"],attribs["alpha"]) self.groupes = {} self.temples = [] self.parent = parent self.settings = Config().instance.settings
def __init__ (self, id_i, name, attrib,parent): self.id = id_i self.name = name self.attrib = attrib self.attrib['icon'] = self.name+".png" self.kingdoms = {} self.color = QColor(int(self.attrib['color'].split(',')[0]),int(self.attrib['color'].split(',')[1]),int(self.attrib['color'].split(',')[2])) self.parent= parent self.geometry = self.loadGeom()
def paintEvent(self, ev): if not self.static_text or not self.static_text.text(): return p = QPainter(self) p.setRenderHint(p.TextAntialiasing) # If text is too long too fit, fade it out at the end self.static_text.setTextWidth(self.rect().width()) sz = self.static_text.size() r = self.rect() p.drawStaticText(0, (r.height() - sz.height()) // 2, self.static_text) if sz.width() > r.width(): g = QLinearGradient(self.rect().topLeft(), self.rect().topRight()) c = QColor(self.sb_background) c.setAlpha(0) g.setColorAt(0, c) g.setColorAt(0.8, c) g.setColorAt(1.0, self.sb_background) p.fillRect(self.rect(), QBrush(g)) p.end()
def _draw_column_data(self, painter, color, xcol, ycol, xmin, xmax, ymin, ymax): painter.setPen( QPen(QColor(color), 2, Qt.SolidLine, Qt.RoundCap)) color = QColor(color) color.setAlpha(40) painter.setBrush(color) path = QPainterPath() path.moveTo(xmin, ymax) for row in self.data.rows: x, y = self._xy_from_data(row[xcol], row[ycol], xmin, xmax, ymin, ymax) path.lineTo(x, y) path.lineTo(xmax, ymax) path.moveTo(xmin, ymax) painter.drawPath(path)
def read_color(col): if QColor.isValidColor(col): return QBrush(QColor(col)) if col.startswith('rgb('): r, g, b = map(int, (x.strip() for x in col[4:-1].split(','))) return QBrush(QColor(r, g, b)) try: r, g, b = col[0:2], col[2:4], col[4:6] r, g, b = int(r, 16), int(g, 16), int(b, 16) return QBrush(QColor(r, g, b)) except Exception: pass
def data(self, index, role): row, col = index.row(), index.column() if not index.isValid(): return '' elif role == Qt.BackgroundRole and self.show_confidence_colors: confidence = self.arraydata[row][self.CONFIDENCE_COL] saturation = 0.40 value = 1.0 red_hue = 0.0 green_hue = 0.333 yellow_hue = 0.1665 if confidence >= 3: return QBrush(QColor.fromHsvF(green_hue, saturation, value)) elif confidence: return QBrush(QColor.fromHsvF(yellow_hue, saturation, value)) else: return QBrush(QColor.fromHsvF(red_hue, saturation, value)) elif role == Qt.CheckStateRole and col == self.ENABLED_COL: if self.arraydata[row][self.ENABLED_COL].checkState(): return Qt.Checked else: return Qt.Unchecked elif role == Qt.DisplayRole and col == self.READER_APP_COL: return unicode(self.arraydata[row][self.READER_APP_COL].text()) elif role == Qt.DisplayRole and col == self.TITLE_COL: return unicode(self.arraydata[row][self.TITLE_COL].text()) elif role == Qt.DisplayRole and col == self.AUTHOR_COL: return unicode(self.arraydata[row][self.AUTHOR_COL].text()) elif role == Qt.DisplayRole and col == self.LAST_ANNOTATION_COL: return unicode(self.arraydata[row][self.LAST_ANNOTATION_COL].text()) elif role == Qt.TextAlignmentRole and (col in self.centered_columns): return Qt.AlignHCenter elif role != Qt.DisplayRole: return None return self.arraydata[index.row()][index.column()]
def __init__(self, parent, current_row, current_key, standard_colheads, standard_colnames): QDialog.__init__(self, parent) self.setup_ui() self.setWindowTitle(_('Create a custom column')) self.heading_label.setText('<b>' + _('Create a custom column')) # Remove help icon on title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) self.setWindowIcon(icon) self.simple_error = partial(error_dialog, self, show=True, show_copy_button=False) for sort_by in [_('Text'), _('Number'), _('Date'), _('Yes/No')]: self.composite_sort_by.addItem(sort_by) self.parent = parent self.parent.cc_column_key = None self.editing_col = current_row is not None self.standard_colheads = standard_colheads self.standard_colnames = standard_colnames self.column_type_box.setMaxVisibleItems(len(self.column_types)) for t in self.column_types: self.column_type_box.addItem(self.column_types[t]['text']) self.column_type_box.currentIndexChanged.connect(self.datatype_changed) all_colors = [unicode(s) for s in list(QColor.colorNames())] self.enum_colors_label.setToolTip('<p>' + ', '.join(all_colors) + '</p>') if not self.editing_col: self.datatype_changed() self.exec_() return self.setWindowTitle(_('Edit custom column')) self.heading_label.setText('<b>' + _('Edit custom column')) self.shortcuts.setVisible(False) idx = current_row if idx < 0: self.simple_error(_('No column selected'), _('No column has been selected')) return col = current_key if col not in parent.custcols: self.simple_error('', _('Selected column is not a user-defined column')) return c = parent.custcols[col] self.column_name_box.setText(c['label']) self.column_heading_box.setText(c['name']) self.column_heading_box.setFocus() ct = c['datatype'] if c['is_multiple']: ct = '*' + ct self.orig_column_number = c['colnum'] self.orig_column_name = col column_numbers = dict(map(lambda x:(self.column_types[x]['datatype'], x), self.column_types)) self.column_type_box.setCurrentIndex(column_numbers[ct]) self.column_type_box.setEnabled(False) if ct == 'datetime': if c['display'].get('date_format', None): self.format_box.setText(c['display'].get('date_format', '')) elif ct in ['composite', '*composite']: self.composite_box.setText(c['display'].get('composite_template', '')) sb = c['display'].get('composite_sort', 'text') vals = ['text', 'number', 'date', 'bool'] if sb in vals: sb = vals.index(sb) else: sb = 0 self.composite_sort_by.setCurrentIndex(sb) self.composite_make_category.setChecked( c['display'].get('make_category', False)) self.composite_contains_html.setChecked( c['display'].get('contains_html', False)) elif ct == 'enumeration': self.enum_box.setText(','.join(c['display'].get('enum_values', []))) self.enum_colors.setText(','.join(c['display'].get('enum_colors', []))) elif ct in ['int', 'float']: if c['display'].get('number_format', None): self.format_box.setText(c['display'].get('number_format', '')) elif ct == 'comments': idx = max(0, self.comments_heading_position.findData(c['display'].get('heading_position', 'hide'))) self.comments_heading_position.setCurrentIndex(idx) idx = max(0, self.comments_type.findData(c['display'].get('interpret_as', 'html'))) self.comments_type.setCurrentIndex(idx) elif ct == 'rating': self.allow_half_stars.setChecked(bool(c['display'].get('allow_half_stars', False))) self.datatype_changed() if ct in ['text', 'composite', 'enumeration']: self.use_decorations.setChecked(c['display'].get('use_decorations', False)) elif ct == '*text': self.is_names.setChecked(c['display'].get('is_names', False)) self.description_box.setText(c['display'].get('description', '')) self.exec_()
__license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' import sys, collections, operator, copy, re from PyQt5.Qt import (Qt, QRectF, QFont, QColor, QPixmap, QGraphicsPixmapItem, QGraphicsItem, QFontMetrics, QPen, QBrush, QGraphicsRectItem) from calibre.ebooks.lrf.fonts import LIBERATION_FONT_MAP from calibre.ebooks.BeautifulSoup import Tag from calibre.ebooks.hyphenate import hyphenate_word WEIGHT_MAP = lambda wt: int((wt / 10.) - 1) NULL = lambda a, b: a COLOR = lambda a, b: QColor(*a) WEIGHT = lambda a, b: WEIGHT_MAP(a) class PixmapItem(QGraphicsPixmapItem): def __init__(self, data, encoding, x0, y0, x1, y1, xsize, ysize): p = QPixmap() p.loadFromData(data, encoding, Qt.AutoColor) w, h = p.width(), p.height() p = p.copy(x0, y0, min(w, x1 - x0), min(h, y1 - y0)) if p.width() != xsize or p.height() != ysize: p = p.scaled(xsize, ysize, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) QGraphicsPixmapItem.__init__(self, p) self.height, self.width = ysize, xsize self.setTransformationMode(Qt.SmoothTransformation) self.setShapeMode(QGraphicsPixmapItem.BoundingRectShape)
def set_ui(self): self.setWindowTitle('SingleRank') self.setObjectName('singlerank') self.resize(self.w, self.h) effect = QGraphicsDropShadowEffect() effect.setOffset(10, 10) effect.setColor(QColor(0, 0, 0, 80)) effect.setBlurRadius(20) effect1 = QGraphicsDropShadowEffect() effect1.setOffset(10, 10) effect1.setColor(QColor(0, 0, 0, 80)) effect1.setBlurRadius(20) self.back2_wi.setObjectName('back') self.back2_wi.resize(self.xr * 793, self.yr * 534) self.back2_wi.move(self.xr * 69, self.yr * 53) self.back2_wi.setGraphicsEffect(effect) self.header1.setObjectName('header') self.header1.resize(self.xr * 172, self.yr * 36) self.header1.move(self.xr * 24, self.yr * 10) self.header1.setText('过往战绩') self.header1.setAlignment(Qt.AlignCenter) self.comeback_but.setObjectName('comeback') self.comeback_but.resize(self.xr * 80, self.yr * 36) self.comeback_but.move(self.xr * 67, self.yr * 467) self.comeback_but.setText('返回') self.comeback_but.clicked.connect(self.come_back) self.comeback_but.setGraphicsEffect(effect1) self.next_but.setObjectName('next') self.next_but.resize(self.zr * 38, self.zr * 38) self.next_but.move(self.xr * 725, self.yr * 468) self.next_but.setStyleSheet('border-radius:{}px;'.format(self.zr * 18)) self.next_but.clicked.connect(self.next) self.table.setObjectName('table') self.table.resize(self.xr * 746, self.yr * 382) self.table.move(self.xr * 24, self.yr * 61) self.tablein.setSpacing(0) self.tablein.setContentsMargins(0, 0, 0, 0) self.table.setLayout(self.tablein) li = ['#f5f0e3', '#cccccc'] for i in range(0, 5): for j in range(0, 4): if j == 3 and i != 0: exec('self.tableheader{}_{} = QPushButton()'.format(i, j)) exec( 'self.tableheader{}_{}.setMinimumHeight(self.yr *382/5)' .format(i, j)) exec('self.tableheader{}_{}.setText("详情")'.format(i, j)) exec( 'self.tableheader{}_{}.clicked.connect(self.details{})' .format(i, j, i)) else: exec('self.tableheader{}_{} = QLabel()'.format(i, j)) exec('self.tableheader{}_{}.setAlignment(Qt.AlignCenter)'. format(i, j)) if i == 0: exec('self.tableheader{}_{}.setObjectName("table_head")'. format(i, j)) exec('self.tableheader{}_{}.setText("{}")'.format( i, j, self.headers[j])) else: exec('self.tableheader{}_{}.setObjectName("table_unit")'. format(i, j)) exec( 'self.tableheader{}_{}.setStyleSheet("background-color:{};")' .format(i, j, li[(i + j) % 2])) exec('self.tablein.addWidget(self.tableheader{}_{}, {}, {})'. format(i, j, i, j)) self.back2_wi.setStyleSheet('#back{border-radius:' + str(self.zr * 20) + 'px;}#header{border-radius:' + str(self.zr * 15) + 'px;font-size:' + str(int(self.zr * 18)) + 'px;}#comeback{border-radius:' + str(self.zr * 15) + 'px;font-size:' + str(int(self.zr * 16)) + 'px;}#table_unit{font-size:' + str(int(self.zr * 18)) + 'px;}#table_head{font-size:' + str(int(self.zr * 20)) + 'px;font-weight:bold}')
def __init__(self, name, color0=QColor("black"), color1=QColor("white"), alpha=(1, 1)): QObject.__init__(self) self.name = name # color is either specified as one argument (which should then be a [3,n] or [4,n] array), # or as two QColors orstring names. if isinstance(color0, (list, tuple)): self._rgb = numpy.array(color0) if self._rgb.shape[1] != 3 or self._rgb.shape[0] < 2: raise TypeError("expected [N,3] (N>=2) array as first argument") else: if isinstance(color0, str): color0 = QColor(color0) if isinstance(color1, str): color1 = QColor(color1) self._rgb = numpy.array([[color0.red(), color0.green(), color0.blue()], [color1.red(), color1.green(), color1.blue()]]) / 255. self._rgb_arg = numpy.arange(self._rgb.shape[0]) / (self._rgb.shape[0] - 1.0) # alpha array self._alpha = numpy.array(alpha).astype(float) self._alpha_arg = numpy.arange(len(alpha)) / (len(alpha) - 1.0) # background brush self._brush = None
def color(self, val): self._color = QColor('#' + val)
class Pointer(QWidget): def __init__(self, gui): QWidget.__init__(self, gui) self.setObjectName('jobs_pointer') self.setVisible(False) self.resize(100, 80) self.animation = QPropertyAnimation(self, "geometry", self) self.animation.setDuration(750) self.animation.setLoopCount(2) self.animation.setEasingCurve(QEasingCurve.Linear) self.animation.finished.connect(self.hide) taily, heady = 0, 55 self.arrow_path = QPainterPath(QPointF(40, taily)) self.arrow_path.lineTo(40, heady) self.arrow_path.lineTo(20, heady) self.arrow_path.lineTo(50, self.height()) self.arrow_path.lineTo(80, heady) self.arrow_path.lineTo(60, heady) self.arrow_path.lineTo(60, taily) self.arrow_path.closeSubpath() c = self.palette().color(QPalette.Active, QPalette.WindowText) self.color = QColor(c) self.color.setAlpha(100) self.brush = QBrush(self.color, Qt.SolidPattern) # from PyQt5.Qt import QTimer # QTimer.singleShot(1000, self.start) @property def gui(self): return self.parent() def point_at(self, frac): return (self.path.pointAtPercent(frac).toPoint() - QPoint(self.rect().center().x(), self.height())) def rect_at(self, frac): return QRect(self.point_at(frac), self.size()) def abspos(self, widget): pos = widget.pos() parent = widget.parent() while parent is not self.gui: pos += parent.pos() parent = parent.parent() return pos def start(self): if config['disable_animations']: return self.setVisible(True) self.raise_() end = self.abspos(self.gui.jobs_button) end = QPointF( end.x() + self.gui.jobs_button.width()/3.0, end.y()+20) start = QPointF(end.x(), end.y() - 0.5*self.height()) self.path = QPainterPath(QPointF(start)) self.path.lineTo(end) self.path.closeSubpath() self.animation.setStartValue(self.rect_at(0.0)) self.animation.setEndValue(self.rect_at(1.0)) self.animation.setDirection(self.animation.Backward) num_keys = 100 for i in xrange(1, num_keys): i /= num_keys self.animation.setKeyValueAt(i, self.rect_at(i)) self.animation.start() def paintEvent(self, ev): p = QPainter(self) p.setRenderHints(p.Antialiasing) p.setBrush(self.brush) p.setPen(Qt.NoPen) p.drawPath(self.arrow_path) p.end()
def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) # Set window background color self.setAutoFillBackground(True) p = self.palette() p.setColor(self.backgroundRole(), QColor('white')) self.setPalette(p) self.setStyleSheet(""" QPushButton[menuButton = "true"]{ border: none; border-radius: 10px; background-color: #3b77d6; font-family: "Helvetica"; font-size: 34px; color: white; padding: 10px; min-height: 60px; align: center; } QPushButton[menuButton = "false"] { border: none; border-radius: 8px; background-color: #3b77d6; font-family: "Helvetica"; font-size: 28px; color: white; padding: 8px; min-width: 180px; min-height: 180px; } QPushButton[mainMenuButton = "true"]{ border: none; border-radius: 10px; background-color: #3b77d6; font-family: "Helvetica"; font-size: 34px; color: white; padding: 10px; min-height: 100px; } QPushButton:hover { background-color: #2f5faa; } QPushButton:pressed { background-color: #244882; } QMenuBar { border: none; background-color: #3b77d6; font-family: "Helvetica"; font-size: 34px; color: white; min-height: 60px; } QMenuBar::item { padding: 15px; margin: 0px } QMenuBar::item::selected { background-color: #2f5faa; } QMenuBar::item::pressed { background-color: #244882; } QLabel { font-family: "Helvetica"; font-size: 28px; color: black; } QLabel[description = "true"] { font-family: "Helvetica"; font-size: 28px; color: #aaaaaa; } QWidget { padding: 10px; } QLineEdit { font-size: 28px; font-family: "Helvetica"; } """) self.show()
def initialize(self, parent, book_id, cid, installed_book, enable_metadata_updates, marvin_db_path): ''' __init__ is called on SizePersistedDialog() shared attributes of interest: .authors .author_sort .cover_hash .pubdate .publisher .rating .series .series_index .title .title_sort .comments .tags .uuid ''' self.setupUi(self) self.book_id = book_id self.cid = cid self.connected_device = parent.opts.gui.device_manager.device self.installed_book = installed_book self.marvin_db_path = marvin_db_path self.opts = parent.opts self.parent = parent self.stored_command = None self.verbose = parent.verbose self.BORDER_LR = 4 self.BORDER_TB = 8 self.GREY_FG = '<font style="color:#A0A0A0">{0}</font>' self.YELLOW_BG = '<font style="background:#FDFF99">{0}</font>' self._log_location(installed_book.title) # Subscribe to Marvin driver change events self.connected_device.marvin_device_signals.reader_app_status_changed.connect( self.marvin_status_changed) #self._log("mismatches:\n%s" % repr(installed_book.metadata_mismatches)) self.mismatches = installed_book.metadata_mismatches self._populate_title() self._populate_title_sort() self._populate_series() self._populate_authors() self._populate_author_sort() self._populate_uuid() self._populate_covers() self._populate_subjects() self._populate_publisher() self._populate_pubdate() self._populate_rating() self._populate_description() # ~~~~~~~~ Export to Marvin button ~~~~~~~~ self.export_to_marvin_button.setIcon(QIcon(os.path.join(self.parent.opts.resources_path, 'icons', 'from_calibre.png'))) self.export_to_marvin_button.clicked.connect(partial(self.store_command, 'export_metadata')) self.export_to_marvin_button.setEnabled(enable_metadata_updates) # ~~~~~~~~ Import from Marvin button ~~~~~~~~ self.import_from_marvin_button.setIcon(QIcon(os.path.join(self.parent.opts.resources_path, 'icons', 'from_marvin.png'))) self.import_from_marvin_button.clicked.connect(partial(self.store_command, 'import_metadata')) self.import_from_marvin_button.setEnabled(enable_metadata_updates) # If no calibre book, or no mismatches, adjust the display accordingly if not self.cid: #self._log("self.cid: %s" % repr(self.cid)) #self._log("self.mismatches: %s" % repr(self.mismatches)) self.calibre_gb.setVisible(False) self.import_from_marvin_button.setVisible(False) self.setWindowTitle(u'Marvin metadata') elif not self.mismatches: # Show both panels, but hide the transfer buttons self.export_to_marvin_button.setVisible(False) self.import_from_marvin_button.setVisible(False) else: self.setWindowTitle(u'Metadata Summary') if False: # Set the Marvin QGroupBox to Marvin red marvin_red = QColor() marvin_red.setRgb(189, 17, 20, alpha=255) palette = QPalette() palette.setColor(QPalette.Background, marvin_red) self.marvin_gb.setPalette(palette) # ~~~~~~~~ Add a Close or Cancel button ~~~~~~~~ self.close_button = QPushButton(QIcon(I('window-close.png')), 'Close') if self.mismatches: self.close_button.setText('Cancel') self.bb.addButton(self.close_button, QDialogButtonBox.RejectRole) self.bb.clicked.connect(self.dispatch_button_click) # Restore position self.resize_dialog()
def __init__(self, color): QColor.__init__(self, color.r, color.g, color.b, 0xff-color.a)
def Random_colors(rng): return [QColor(r.randint(0,255),r.randint(0,255),r.randint(0,255)) for x in range(int(rng))]
def fset(self, val): self._color = QColor('#' + val)
def __init__(self, parent, current_row, current_key, standard_colheads, standard_colnames): QDialog.__init__(self, parent) self.setup_ui() self.setWindowTitle(_('Create a custom column')) self.heading_label.setText('<b>' + _('Create a custom column')) # Remove help icon on title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags() & (~Qt.WindowContextHelpButtonHint)) self.setWindowIcon(icon) self.simple_error = partial(error_dialog, self, show=True, show_copy_button=False) for sort_by in [_('Text'), _('Number'), _('Date'), _('Yes/No')]: self.composite_sort_by.addItem(sort_by) self.parent = parent self.parent.cc_column_key = None self.editing_col = current_row is not None self.standard_colheads = standard_colheads self.standard_colnames = standard_colnames self.column_type_box.setMaxVisibleItems(len(self.column_types)) for t in self.column_types: self.column_type_box.addItem(self.column_types[t]['text']) self.column_type_box.currentIndexChanged.connect(self.datatype_changed) all_colors = [unicode(s) for s in list(QColor.colorNames())] self.enum_colors_label.setToolTip('<p>' + ', '.join(all_colors) + '</p>') if not self.editing_col: self.datatype_changed() self.exec_() return self.setWindowTitle(_('Edit custom column')) self.heading_label.setText('<b>' + _('Edit custom column')) self.shortcuts.setVisible(False) idx = current_row if idx < 0: self.simple_error(_('No column selected'), _('No column has been selected')) return col = current_key if col not in parent.custcols: self.simple_error( '', _('Selected column is not a user-defined column')) return c = parent.custcols[col] self.column_name_box.setText(c['label']) self.column_heading_box.setText(c['name']) self.column_heading_box.setFocus() ct = c['datatype'] if c['is_multiple']: ct = '*' + ct self.orig_column_number = c['colnum'] self.orig_column_name = col column_numbers = dict( map(lambda x: (self.column_types[x]['datatype'], x), self.column_types)) self.column_type_box.setCurrentIndex(column_numbers[ct]) self.column_type_box.setEnabled(False) if ct == 'datetime': if c['display'].get('date_format', None): self.format_box.setText(c['display'].get('date_format', '')) elif ct in ['composite', '*composite']: self.composite_box.setText(c['display'].get( 'composite_template', '')) sb = c['display'].get('composite_sort', 'text') vals = ['text', 'number', 'date', 'bool'] if sb in vals: sb = vals.index(sb) else: sb = 0 self.composite_sort_by.setCurrentIndex(sb) self.composite_make_category.setChecked(c['display'].get( 'make_category', False)) self.composite_contains_html.setChecked(c['display'].get( 'contains_html', False)) elif ct == 'enumeration': self.enum_box.setText(','.join(c['display'].get('enum_values', []))) self.enum_colors.setText(','.join(c['display'].get( 'enum_colors', []))) elif ct in ['int', 'float']: if c['display'].get('number_format', None): self.format_box.setText(c['display'].get('number_format', '')) elif ct == 'comments': idx = max( 0, self.comments_heading_position.findData(c['display'].get( 'heading_position', 'hide'))) self.comments_heading_position.setCurrentIndex(idx) idx = max( 0, self.comments_type.findData(c['display'].get( 'interpret_as', 'html'))) self.comments_type.setCurrentIndex(idx) elif ct == 'rating': self.allow_half_stars.setChecked( bool(c['display'].get('allow_half_stars', False))) self.datatype_changed() if ct in ['text', 'composite', 'enumeration']: self.use_decorations.setChecked(c['display'].get( 'use_decorations', False)) elif ct == '*text': self.is_names.setChecked(c['display'].get('is_names', False)) self.description_box.setText(c['display'].get('description', '')) self.exec_()
def accept(self): col = unicode(self.column_name_box.text()).strip() if not col: return self.simple_error('', _('No lookup name was provided')) if col.startswith('#'): col = col[1:] if re.match(r'^\w*$', col) is None or not col[0].isalpha() or col.lower() != col: return self.simple_error( '', _('The lookup name must contain only ' 'lower case letters, digits and underscores, and start with a letter' )) if col.endswith('_index'): return self.simple_error( '', _('Lookup names cannot end with _index, ' 'because these names are reserved for the index of a series column.' )) col_heading = unicode(self.column_heading_box.text()).strip() coldef = self.column_types[self.column_type_box.currentIndex()] col_type = coldef['datatype'] if col_type[0] == '*': col_type = col_type[1:] is_multiple = True else: is_multiple = False if not col_heading: return self.simple_error('', _('No column heading was provided')) db = self.parent.gui.library_view.model().db key = db.field_metadata.custom_field_prefix + col bad_col = False if key in self.parent.custcols: if not self.editing_col or \ self.parent.custcols[key]['colnum'] != self.orig_column_number: bad_col = True if bad_col: return self.simple_error( '', _('The lookup name %s is already used') % col) bad_head = False for t in self.parent.custcols: if self.parent.custcols[t]['name'] == col_heading: if not self.editing_col or \ self.parent.custcols[t]['colnum'] != self.orig_column_number: bad_head = True for t in self.standard_colheads: if self.standard_colheads[t] == col_heading: bad_head = True if bad_head: return self.simple_error( '', _('The heading %s is already used') % col_heading) display_dict = {} if col_type == 'datetime': if unicode(self.format_box.text()).strip(): display_dict = { 'date_format': unicode(self.format_box.text()).strip() } else: display_dict = {'date_format': None} elif col_type == 'composite': if not unicode(self.composite_box.text()).strip(): return self.simple_error( '', _('You must enter a template for' ' composite columns')) display_dict = { 'composite_template': unicode(self.composite_box.text()).strip(), 'composite_sort': ['text', 'number', 'date', 'bool'][self.composite_sort_by.currentIndex()], 'make_category': self.composite_make_category.isChecked(), 'contains_html': self.composite_contains_html.isChecked(), } elif col_type == 'enumeration': if not unicode(self.enum_box.text()).strip(): return self.simple_error( '', _('You must enter at least one' ' value for enumeration columns')) l = [ v.strip() for v in unicode(self.enum_box.text()).split(',') if v.strip() ] l_lower = [v.lower() for v in l] for i, v in enumerate(l_lower): if v in l_lower[i + 1:]: return self.simple_error( '', _('The value "{0}" is in the ' 'list more than once, perhaps with different case'). format(l[i])) c = unicode(self.enum_colors.text()) if c: c = [ v.strip() for v in unicode(self.enum_colors.text()).split(',') ] else: c = [] if len(c) != 0 and len(c) != len(l): return self.simple_error( '', _('The colors box must be empty or ' 'contain the same number of items as the value box')) for tc in c: if tc not in QColor.colorNames() and not re.match( "#(?:[0-9a-f]{3}){1,4}", tc, re.I): return self.simple_error( '', _('The color {0} is unknown').format(tc)) display_dict = {'enum_values': l, 'enum_colors': c} elif col_type == 'text' and is_multiple: display_dict = {'is_names': self.is_names.isChecked()} elif col_type in ['int', 'float']: if unicode(self.format_box.text()).strip(): display_dict = { 'number_format': unicode(self.format_box.text()).strip() } else: display_dict = {'number_format': None} elif col_type == 'comments': display_dict['heading_position'] = type(u'')( self.comments_heading_position.currentData()) display_dict['interpret_as'] = type(u'')( self.comments_type.currentData()) elif col_type == 'rating': display_dict['allow_half_stars'] = bool( self.allow_half_stars.isChecked()) if col_type in ['text', 'composite', 'enumeration' ] and not is_multiple: display_dict['use_decorations'] = self.use_decorations.checkState() display_dict['description'] = self.description_box.text().strip() if not self.editing_col: self.parent.custcols[key] = { 'label': col, 'name': col_heading, 'datatype': col_type, 'display': display_dict, 'normalized': None, 'colnum': None, 'is_multiple': is_multiple, } self.parent.cc_column_key = key else: self.parent.custcols[self.orig_column_name]['label'] = col self.parent.custcols[self.orig_column_name]['name'] = col_heading self.parent.custcols[self.orig_column_name]['display'].update( display_dict) self.parent.custcols[self.orig_column_name]['*edited'] = True self.parent.custcols[self.orig_column_name]['*must_restart'] = True self.parent.cc_column_key = key QDialog.accept(self)
def fset(self, colors): num = min(len(colors), QColorDialog.customCount()) for i in xrange(num): QColorDialog.setCustomColor(i, QColor(*colors[i]))
def search(self): text = self.search_space.text() print(text) self.listWidget.clear() self.listWidget.setFocus() try: url = "https://bookbrainz.org/ws/search/?q=\"" + text + "\"&mode=\"search\"" hits = request_get(url)['hits'] except: return numQueries = len(hits) act = 0 for i in range(numQueries): enttype = hits[i]['_source']['_type'] if not enttype in ['Publication', 'Work', 'Edition']: continue print(hits[i]) item = QListWidgetItem("%i. %s BBID : %i" % ((act + 1), hits[i]['_source']['default_alias']['name'], 1)) Qcol = QColor() if i % 2 == 0: Qcol.setRed(240) Qcol.setGreen(255) Qcol.setBlue(255) else: Qcol.setRed(220) Qcol.setGreen(255) Qcol.setBlue(240) item.setBackground(QBrush(Qcol)) self.listWidget.addItem(item) act += 1 self.listWidget.setFocus() self.searchExecutionButton.setFocus()
def theme_to_colors(theme): colors = {k: QColor('#' + theme[k]) for k in ColorTheme._fields} return ColorTheme(**colors)
class MainWindow(QMainWindow, MainQtGui.Ui_MainWindow, QObject): """PyContact Application Main Window with timeline.""" def closeEvent(self, event): """Closing application when Exit on MainWindow is clicked.""" print("Closing Application") event.accept() QApplication.quit() def __init__(self, parent=None): self.config = None self.analysis = None self.maps = None super(MainWindow, self).__init__(parent) self.contacts = [] self.filteredContacts = [] self.setupUi(self) self.setWindowTitle("PyContact") # painter contains both labels and frame boxes for drawing self.painter = Canvas() self.scrollArea.setWidget(self.painter) self.actionExportData.triggered.connect(self.pushExport) self.actionLoad_Data.triggered.connect(self.loadDataPushed) self.actionExport_Session.triggered.connect(self.exportSession) self.actionImport_Session.triggered.connect(self.importSession) self.actionShow_Info.triggered.connect(self.showDeveloperInfo) # settings and filters self.settingsView = PreferencesWidget() self.settingsView.applySettingsButton.clicked.connect( self.updateSettings) self.applyFilterButton.clicked.connect(self.updateFilters) # statistics self.statisticsButton.clicked.connect(self.showStatistics) # color picker self.settingsView.pickColorButton.clicked.connect(self.showColorPicker) self.customColor = QColor(230, 50, 0) self.settingsView.pickColorButton.setStyleSheet( "QWidget { background-color: %s }" % self.customColor.name()) # frames stride posIntValidator = QIntValidator() posIntValidator.setBottom(1) self.frameStrideField.setValidator(posIntValidator) # analysis button self.analysisButton.clicked.connect(self.analyzeDataPushed) # contact area button self.actionContact_Area_Calculations.triggered.connect( self.showContactAreaView) # preferences self.actionPreferences.triggered.connect(self.openPrefs) # apply color button, outdated? self.colorScheme = ColorScheme.bbsc self.actionDefault.triggered.connect(self.loadDefault) self.currentSelection1 = "-" self.currentSelection2 = "-" # setup of extra widgets self.exportWidget = ExportTabWidget() self.sasaView = SasaWidget() self.statisticsView = None self.analysis_state = False self.vismode = False self.visModeButton.setCheckable(True) self.visModeButton.setChecked(False) self.visModeButton.clicked.connect(self.switchedToVisMode) self.vmdpanel = VMDControlPanel() self.actionVMD_Remote_Control.triggered.connect( self.showVMDControlPanel) self.painter.clickedRowSignal.connect(self.updateVMDSelections) self.painter.clickedColumnSignal.connect(self.updateVMDFrame) self.updateSettings() self.updateFilters() # self.tableTest = Widget() # self.tableTest.setGeometry(100, 100, 400, 400) # self.tableTest.show() # from ..db.DbReader import read_residue_db_all # res = read_residue_db_all() # residueList = [] # 1st: name, 2nd scpolarity # for k in res: # residueList.appen([k["name"], k["scpolarity"]]) self.actionDefault.setText("Load sample data") def showVMDControlPanel(self): """Shows the VMD control panel, to remotely access VMD from PyContact.""" self.vmdpanel.show() def showContactAreaView(self): """Shows the SASA computation panel.""" self.sasaView.show() if self.analysis: self.sasaView.setFilePaths(self.analysis.getFilePaths()) def switchedToVisMode(self): """Switch to vis mode, to show selected contacts directly in VMD.""" if self.visModeButton.isChecked(): self.vismode = True # conversions with clicked frames are not allowed self.frameStrideField.setText("1") else: self.vismode = False self.painter.switchToVisMode(self.vismode) self.updateSettings() self.updateFilters() @pyqtSlot() def updateVMDSelections(self): """Updates the selected contact in VMD via the vmd panel.""" if self.vmdpanel.connected: self.vmdpanel.updateSelections( self.analysis.sel1text, self.analysis.sel2text, [self.filteredContacts[self.painter.globalClickedRow]]) @pyqtSlot() def updateVMDFrame(self): """Updates the selected frame in VMD via the vmd panel.""" if self.vmdpanel.connected: self.vmdpanel.gotoVMDFrame(self.painter.clickedColumn) def updateSelectionLabels(self, sel1, sel2): """Updates the current selection in the info labels.""" self.currentSelection1 = sel1 self.currentSelection2 = sel2 self.selection1label.setText(sel1) self.selection2label.setText(sel2) def importSession(self): """Imports a saved session from file.""" fnames = QFileDialog.getOpenFileNames(self, "Open file") importfile = "" for f in fnames[0]: importfile = f break if importfile == "" or len(fnames) == 0: return self.contacts, arguments, trajArgs, self.maps, contactResults = DataHandler.importSessionFromFile( importfile) self.analysis = Analyzer(*arguments) self.analysis.contactResults = contactResults self.analysis.setTrajectoryData(*trajArgs) self.analysis.finalAccumulatedContacts = self.contacts self.sasaView.setFilePaths(*self.analysis.getFilePaths()) self.exportWidget.setFilePaths(*self.analysis.getFilePaths()) self.updateSelectionLabels(arguments[5], arguments[6]) self.updateSettings() self.updateFilters() def exportSession(self): """Exports the current session to file.""" fileName = QFileDialog.getSaveFileName(self, 'Export file') filestring = fileName[0] if filestring == "": return if self.contacts is not None and self.analysis is not None: self.setInfoLabel("Exporting current session...") DataHandler.writeSessionToFile(filestring, self.analysis) self.cleanInfoLabel() else: box = ErrorBox(ErrorMessages.NOEXPDATA) box.exec_() return def loadDefault(self): """Loads the default session.""" self.contacts, arguments, trajArgs, self.maps, contactResults = \ DataHandler.importSessionFromFile(DEFAULTSESSION) self.analysis = Analyzer(*arguments) self.analysis.contactResults = contactResults self.analysis.setTrajectoryData(*trajArgs) self.analysis.finalAccumulatedContacts = self.contacts self.sasaView.setFilePaths(*self.analysis.getFilePaths()) self.exportWidget.setFilePaths(*self.analysis.getFilePaths()) self.updateSelectionLabels(arguments[5], arguments[6]) self.updateSettings() self.updateFilters() def loadDataPushed(self): """Loads the trajectory data with the chosen initial parameters.""" self.config, result = FileLoaderDialog.getConfig() if result == 1: QApplication.processEvents() self.setInfoLabel( "Loading trajectory and running atomic contact analysis...") nproc = int(self.settingsView.coreBox.value()) self.analysis = Analyzer(self.config.psf, self.config.dcd, self.config.cutoff, self.config.hbondcutoff, self.config.hbondcutangle, self.config.sel1text, self.config.sel2text) QApplication.processEvents() try: self.analysis.runFrameScan(nproc) except: box = ErrorBox( "Error while loading data: Probably you specified an atom selection with 0 atoms or invalid input files." ) box.exec_() self.loadDataPushed() self.setInfoLabel("%d frames loaded." % len(self.analysis.contactResults)) self.updateSelectionLabels(self.config.sel1text, self.config.sel2text) self.sasaView.setFilePaths(*self.analysis.getFilePaths()) self.exportWidget.setFilePaths(*self.analysis.getFilePaths()) @pyqtSlot(float) def updateAnalyzedFrames(self, value): """Handles the progress bar update.""" # print("Updating frames", value) self.progressBar.setValue(100 * value) QApplication.processEvents() def setInfoLabel(self, txt): """Sets the Info label text.""" self.statusLabel.setText(txt) def cleanInfoLabel(self): """Clears the Info label text.""" self.setInfoLabel("-") def analyzeDataPushed(self): """Handles the Analyzer after the Accumulation maps have been set.""" if self.analysis is None: box = ErrorBox(ErrorMessages.NODATA_PROMPTLOAD) box.exec_() return self.maps, result = AnalysisDialog.getMapping() if result == 1: self.analysis.frameUpdate.connect(self.updateAnalyzedFrames) self.setInfoLabel("Analyzing contacts...") map1 = self.maps[0] map2 = self.maps[1] nproc = int(self.settingsView.coreBox.value()) self.contacts = self.analysis.runContactAnalysis(map1, map2, nproc) self.progressBar.setValue(0) self.setInfoLabel("Updating timeline...") QApplication.processEvents() self.updateSettings() self.updateFilters() self.cleanInfoLabel() def updateSettings(self): """Updates the settings chosen from the settings view.""" if self.settingsView.bbscScoreRadioButton.isChecked(): self.colorScheme = ColorScheme.bbsc elif self.settingsView.customColorRadioButton.isChecked(): self.colorScheme = ColorScheme.custom self.painter.nsPerFrame = float( self.settingsView.nsPerFrameField.text()) self.painter.threshold = float(self.settingsView.thresholdField.text()) self.painter.rendered = False self.painter.colorScheme = self.colorScheme self.painter.customColor = self.customColor self.painter.repaint() self.painter.update() def updateFilters(self): """Updates the chosen filters in MainWindow.""" if self.vismode is True: self.frameStrideField.setText("1") stride = int(self.frameStrideField.text()) if stride < 1: stride = 1 QApplication.processEvents() self.frameStrideField.setText(str(stride)) # print("stride: ", stride) self.painter.merge = stride self.painter.labelView.clean() self.painter.showHbondScores = False # total time filter totalTimeActive = self.activeTotalTimeCheckbox.isChecked() scoreActive = self.activeScoreCheckbox.isChecked() sortingActive = self.activeSortingBox.isChecked() onlyActive = self.onlyBoxActiveCheckbox.isChecked() filterActive = (totalTimeActive or scoreActive or sortingActive or onlyActive) weightActive = False # only filter given range rangeFilterActive = self.filterRangeCheckbox.isChecked() if len(self.contacts) > 0: lower = int(self.lowerRangeField.text()) - 1 upper = self.upperRangeField.text() if upper == "end": upper = len(self.contacts[0].scoreArray) else: upper = int(upper) if lower < 0: lower = 0 self.painter.range = [lower, upper] self.painter.rangeFilterActive = False self.filteredContacts = copy.deepcopy(self.contacts) # residue range filter range_filter = RangeFilter("resrange") self.filteredContacts = range_filter.filterByRange( self.filteredContacts, self.residARangeField.text(), self.residBRangeField.text(), AccumulationMapIndex.resid) self.filteredContacts = range_filter.filterByRange( self.filteredContacts, self.atomAIndexField.text(), self.atomBIndexField.text(), AccumulationMapIndex.index) # aminoacids name filter name_filter = NameFilter("name") self.filteredContacts = name_filter.filterContactsByName( self.filteredContacts, self.residANameField.text(), self.residBNameField.text(), AccumulationMapIndex.resname) self.filteredContacts = name_filter.filterContactsByName( self.filteredContacts, self.atomANameField.text(), self.atomBNameField.text(), AccumulationMapIndex.name) # range filter if rangeFilterActive: self.painter.rangeFilterActive = True frameRangeFilter = FrameFilter("framer") self.filteredContacts = frameRangeFilter.extractFrameRange( self.filteredContacts, [lower, upper]) for c in self.filteredContacts: c.setScores() c.setContactType() # weight functions if weightActive: if self.currentFunctionType == FunctionType.sigmoid: print("sig weight") x0 = float(self.sigX0Field.text()) L = float(self.sigLField.text()) k = float(self.sigKField.text()) y0 = float(self.sigY0Field.text()) sig = SigmoidWeightFunction( "sig", np.arange(0, len(self.contacts[0].scoreArray), 1), x0, L, k, y0) self.filteredContacts = sig.weightContactFrames( self.filteredContacts) elif self.currentFunctionType == FunctionType.rect: x0 = float(self.rectX0Field.text()) x1 = float(self.rectX1Field.text()) h = float(self.rectHField.text()) y0 = float(self.rectY0Field.text()) rect = RectangularWeightFunction( "rect", np.arange(0, len(self.contacts[0].scoreArray), 1), x0, x1, h, y0) self.filteredContacts = rect.weightContactFrames( self.filteredContacts) elif self.currentFunctionType == FunctionType.linear: y0 = float(self.linY0Field.text()) y1 = float(self.linY1Field.text()) lin = LinearWeightFunction( "rect", np.arange(0, len(self.contacts[0].scoreArray), 1), y0, y1) self.filteredContacts = lin.weightContactFrames( self.filteredContacts) # other filters if filterActive: if totalTimeActive: operator = self.compareTotalTimeDropdown.currentText() value = float(self.totalTimeField.text()) filter = TotalTimeFilter("tottime", operator, value) self.filteredContacts = filter.filterContacts( self.filteredContacts) if scoreActive: operator = self.compareScoreDropdown.currentText() value = float(self.scoreField.text()) filter = ScoreFilter("score", operator, value, self.meanDropdown.currentText()) self.filteredContacts = filter.filterContacts( self.filteredContacts) if sortingActive: key = self.sortingKeyDropdown.currentText() descending = SortingOrder.mapping[ self.sortingOrderDropdown.currentText()] sorter = Sorting("sorting", key, descending) sorter.setThresholdAndNsPerFrame( float(self.settingsView.thresholdField.text()), float(self.settingsView.nsPerFrameField.text())) self.filteredContacts = sorter.sortContacts( self.filteredContacts) if onlyActive: key = self.selectOnlyToolbox.currentText() only = OnlyFilter("only", key, 0) self.filteredContacts = only.filterContacts( self.filteredContacts) if key == "hbonds": self.painter.showHbondScores = True self.painter.contacts = self.filteredContacts self.painter.rendered = False self.painter.repaint() self.painter.update() if len(self.filteredContacts) == 0: self.painter.labelView.clean() else: # no weight or filters self.painter.showHbondScores = False self.painter.contacts = self.filteredContacts self.painter.rendered = False self.painter.repaint() self.painter.update() # Update data for export self.exportWidget.setContacts(self.filteredContacts) if self.maps is not None: self.exportWidget.setMaps(self.maps[0], self.maps[1]) self.exportWidget.setMapLabels(self.analysis.sel1text, self.analysis.sel2text) self.exportWidget.setThresholdAndNsPerFrame(self.painter.threshold, self.painter.nsPerFrame) def openPrefs(self): """Opens the preferences panel.""" self.settingsView.show() def showStatistics(self): """Shows general statistics of the analyzed data over all frames.""" if len(self.contacts) == 0 or self.contacts is None: box = ErrorBox(ErrorMessages.NOSCORES_PROMPTANALYSIS) box.exec_() return self.statisticsView = Statistics(self.contacts) self.statisticsView.showNormal() def showDeveloperInfo(self): """Shows information about the contributing authors.""" d = QDialog() grid = QGridLayout() d.setLayout(grid) info = QLabel("Developers: Maximilian Scheurer and Peter Rodenkirch") info2 = QLabel( "Departments: TCBG, University of Illinois at Urbana-Champaign; BZH Heidelberg University" ) mail = QLabel( "Contact: [email protected], [email protected]" ) copyright = QLabel("Version 1.0, May 2017") grid.addWidget(info, 0, 0) grid.addWidget(info2, 1, 0) grid.addWidget(mail, 2, 0) grid.addWidget(copyright, 3, 0) d.setWindowTitle("Developer Info") d.resize(150, 80) d.setWindowModality(Qt.ApplicationModal) d.exec_() def pushExport(self): """Opens the export panel.""" self.exportWidget.valueUpdated.connect(self.handleExportUpdate) self.exportWidget.setContacts(self.filteredContacts) if self.maps is not None: self.exportWidget.setMaps(self.maps[0], self.maps[1]) self.exportWidget.setMapLabels(self.analysis.sel1text, self.analysis.sel2text) self.exportWidget.setThresholdAndNsPerFrame(self.painter.threshold, self.painter.nsPerFrame) self.exportWidget.show() @QtCore.Slot(str, str) def handleExportUpdate(self, fileName, fileType): """Handles the paint event after the export of the current view has been initiated.""" print("test") if fileType == "PNG": if len(fileName) > 0: print("Saving current view to ", fileName) currentView = self.painter.grab() currentView.save(fileName) elif fileType == "SVG": if len(fileName) > 0: print("Saving current view to ", fileName) generator = QSvgGenerator() generator.setFileName(fileName) generator.setSize(self.painter.size()) generator.setViewBox(self.painter.rect()) self.painter.renderContact(generator) self.painter.rendered = False self.painter.repaint() self.painter.update() def showColorPicker(self): """Shows a color picker for the current view.""" col = QColorDialog.getColor() self.customColor = col if col.isValid(): self.settingsView.pickColorButton.setStyleSheet( "QWidget { background-color: %s }" % self.customColor.name())
def fill_in_table(self, tags, tag_to_match, ttm_is_first_letter): data = self.get_book_ids(self.apply_vl_checkbox.isChecked()) self.all_tags = {} filter_text = icu_lower(unicode_type(self.filter_box.text())) for k,v,count in data: if not filter_text or self.string_contains(filter_text, icu_lower(v)): self.all_tags[v] = {'key': k, 'count': count, 'cur_name': v, 'is_deleted': k in self.to_delete} self.original_names[k] = v if self.is_enumerated: self.edit_delegate.set_completion_data(self.enum_permitted_values) else: self.edit_delegate.set_completion_data(self.original_names.values()) self.ordered_tags = sorted(self.all_tags.keys(), key=self.sorter) if tags is None: tags = self.ordered_tags select_item = None self.table.blockSignals(True) self.table.clear() self.table.setColumnCount(3) self.name_col = QTableWidgetItem(self.category_name) self.table.setHorizontalHeaderItem(0, self.name_col) self.count_col = QTableWidgetItem(_('Count')) self.table.setHorizontalHeaderItem(1, self.count_col) self.was_col = QTableWidgetItem(_('Was')) self.table.setHorizontalHeaderItem(2, self.was_col) self.table.setRowCount(len(tags)) for row,tag in enumerate(tags): item = NameTableWidgetItem(self.sorter) item.set_is_deleted(self.all_tags[tag]['is_deleted']) _id = self.all_tags[tag]['key'] item.setData(Qt.ItemDataRole.UserRole, _id) item.set_initial_text(tag) if _id in self.to_rename: item.setText(self.to_rename[_id]) else: item.setText(tag) if self.is_enumerated and unicode_type(item.text()) not in self.enum_permitted_values: item.setBackground(QColor('#FF2400')) item.setToolTip( '<p>' + _("This is not one of this column's permitted values ({0})" ).format(', '.join(self.enum_permitted_values)) + '</p>') item.setFlags(item.flags() | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEditable) self.table.setItem(row, 0, item) if select_item is None: if ttm_is_first_letter: if primary_startswith(tag, tag_to_match): select_item = item elif tag == tag_to_match: select_item = item item = CountTableWidgetItem(self.all_tags[tag]['count']) # only the name column can be selected item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsSelectable|Qt.ItemFlag.ItemIsEditable)) self.table.setItem(row, 1, item) item = QTableWidgetItem() item.setFlags(item.flags() & ~(Qt.ItemFlag.ItemIsSelectable|Qt.ItemFlag.ItemIsEditable)) if _id in self.to_rename or _id in self.to_delete: item.setData(Qt.ItemDataRole.DisplayRole, tag) self.table.setItem(row, 2, item) if self.last_sorted_by == 'name': self.table.sortByColumn(0, self.name_order) elif self.last_sorted_by == 'count': self.table.sortByColumn(1, self.count_order) else: self.table.sortByColumn(2, self.was_order) if select_item is not None: self.table.setCurrentItem(select_item) self.table.setFocus(True) self.start_find_pos = select_item.row() else: self.table.setCurrentCell(0, 0) self.search_box.setFocus() self.start_find_pos = -1 self.table.blockSignals(False)
def initDAUI(self): # 行数清零,清除内容 self.tableWidget.setRowCount(0) self.tableWidget.clear() # 获取主界面的e,fn值 e = MainPresenter.e fn = MainPresenter.fn self.label_a.setText(str(fn)) self.label_b.setText(str(e)) self.tableWidget.setColumnCount(5) # 修改为动态插入行 # self.tableWidget.setRowCount(6) self.tableWidget.setHorizontalHeaderLabels( ['a', 'b', 'gcd(a, b)', 'x', 'y']) a = fn b = e (R, G, B) = (255, 255, 255) bgcolor_b = QColor(R, G, B) i = 0 while (1): # 填充辗转相除部分的数据 if not (a == 1 or b == 1): self.tableWidget.insertRow(i) data_a = QTableWidgetItem(str(a)) data_b = QTableWidgetItem(str(b)) gcd = self.gcd(a, b) data_gcd = QTableWidgetItem(str(gcd)) bgcolor_a = bgcolor_b (R, G, B) = self.randcolor(R, G, B) bgcolor_b = QColor(R, G, B) data_a.setBackground(bgcolor_a) data_b.setBackground(bgcolor_b) self.tableWidget.setItem(i, 0, data_a) self.tableWidget.setItem(i, 1, data_b) self.tableWidget.setItem(i, 2, data_gcd) (a, b) = self.eachdivide(a, b) i = i + 1 # 填充后半部分的数据 if (b == 1): self.tableWidget.insertRow(i) data_a = QTableWidgetItem(str(a)) data_b = QTableWidgetItem(str(b)) gcd = self.gcd(a, b) data_gcd = QTableWidgetItem(str(gcd)) data_a.setBackground(bgcolor_b) self.tableWidget.setItem(i, 0, data_a) self.tableWidget.setItem(i, 1, data_b) self.tableWidget.setItem(i, 2, data_gcd) x = 0 y = int((1 - a * x) / b) data_x = QTableWidgetItem(str(x)) data_y = QTableWidgetItem(str(y)) (R, G, B) = self.randcolor(R, G, B) bgcolor_y = QColor(R, G, B) data_y.setBackground(bgcolor_y) self.tableWidget.setItem(i, 3, data_x) self.tableWidget.setItem(i, 4, data_y) j = i while not i == 0: j = j + 1 i = i - 1 self.tableWidget.insertRow(j) a = self.tableWidget.item(i, 0).text() b = self.tableWidget.item(i, 1).text() gcd = self.gcd(int(a), int(b)) data_a = QTableWidgetItem(str(a)) data_b = QTableWidgetItem(str(b)) data_gcd = QTableWidgetItem(str(gcd)) self.tableWidget.setItem(j, 0, data_a) self.tableWidget.setItem(j, 1, data_b) self.tableWidget.setItem(j, 2, data_gcd) # print(a) # print(b) # print(x, y) (x, y) = self.gcdgetxy(int(a), int(b), y) data_x = QTableWidgetItem(str(x)) data_y = QTableWidgetItem(str(y)) bgcolor_x = bgcolor_y (R, G, B) = self.randcolor(R, G, B) bgcolor_y = QColor(R, G, B) data_x.setBackground(bgcolor_x) data_y.setBackground(bgcolor_y) self.tableWidget.setItem(j, 3, data_x) self.tableWidget.setItem(j, 4, data_y) break # 如果最后模数为负,则取正 result_d = self.tableWidget.item(j, 4).text() if (int(result_d) < 0): d = int(result_d) + fn data_d = QTableWidgetItem(str(d)) self.tableWidget.setItem(j, 4, data_d)
def set_cg_color(self, val): self.cg_bg_widget.bcol = QColor(*val) self.cg_bg_widget.update_brush()
def _paint_progress(self): if self._bar_map is None: return self._bar_map.fill(Qt.transparent) painter = QPainter(self._bar_map) w = self.width() hw = self._handle_width w -= hw h = self.height() if self.maximum() == 0: tw = 0 else: tw = w / self.maximum() hh = self._bar_height painter.translate(hw / 2, 0) painter.fillRect( QRect(0, (h - hh) / 2, w, hh), self.palette().dark().color() ) shot = state.get('current_shot') job = state.get('current_job') body_mode = state.get('body_mode') if shot is not None and body_mode is BodyMode.PLAYBACK: progress = self._entity.get_cache_progress() t_color = self.palette().midlight().color() c_color = QColor('#DB2A71') sf, ef = shot.frame_range closeup_camera = state.get('closeup_camera') if isinstance(progress, tuple): progress = {} progress_thumb = progress.get(CameraCacheType.THUMBNAIL, []) progress_origin = progress.get(CameraCacheType.ORIGINAL, []) is_closeup = closeup_camera and closeup_camera in progress_origin i = 0 for f in range(sf, ef + 1): if f in progress_thumb: alpha = progress_thumb[f] if alpha > 1.0: alpha = 1.0 t_color.setAlphaF(float(alpha)) painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), t_color ) if is_closeup and f in progress_origin[closeup_camera]: painter.fillRect( QRect(i * tw, (h - hh) / 2 - 2, math.ceil(tw), 2), c_color ) i += 1 elif job is not None and body_mode is BodyMode.MODEL: progress, tasks = self._entity.get_cache_progress() t_color = self.palette().midlight().color() i = 0 for f in job.frames: if f in progress: painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), t_color ) elif f in tasks: task_state = tasks[f] painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), self._deadline_color[task_state] ) i += 1 painter.end()
def __init__(self, parent=None): self.config = None self.analysis = None self.maps = None super(MainWindow, self).__init__(parent) self.contacts = [] self.filteredContacts = [] self.setupUi(self) self.setWindowTitle("PyContact") # painter contains both labels and frame boxes for drawing self.painter = Canvas() self.scrollArea.setWidget(self.painter) self.actionExportData.triggered.connect(self.pushExport) self.actionLoad_Data.triggered.connect(self.loadDataPushed) self.actionExport_Session.triggered.connect(self.exportSession) self.actionImport_Session.triggered.connect(self.importSession) self.actionShow_Info.triggered.connect(self.showDeveloperInfo) # settings and filters self.settingsView = PreferencesWidget() self.settingsView.applySettingsButton.clicked.connect( self.updateSettings) self.applyFilterButton.clicked.connect(self.updateFilters) # statistics self.statisticsButton.clicked.connect(self.showStatistics) # color picker self.settingsView.pickColorButton.clicked.connect(self.showColorPicker) self.customColor = QColor(230, 50, 0) self.settingsView.pickColorButton.setStyleSheet( "QWidget { background-color: %s }" % self.customColor.name()) # frames stride posIntValidator = QIntValidator() posIntValidator.setBottom(1) self.frameStrideField.setValidator(posIntValidator) # analysis button self.analysisButton.clicked.connect(self.analyzeDataPushed) # contact area button self.actionContact_Area_Calculations.triggered.connect( self.showContactAreaView) # preferences self.actionPreferences.triggered.connect(self.openPrefs) # apply color button, outdated? self.colorScheme = ColorScheme.bbsc self.actionDefault.triggered.connect(self.loadDefault) self.currentSelection1 = "-" self.currentSelection2 = "-" # setup of extra widgets self.exportWidget = ExportTabWidget() self.sasaView = SasaWidget() self.statisticsView = None self.analysis_state = False self.vismode = False self.visModeButton.setCheckable(True) self.visModeButton.setChecked(False) self.visModeButton.clicked.connect(self.switchedToVisMode) self.vmdpanel = VMDControlPanel() self.actionVMD_Remote_Control.triggered.connect( self.showVMDControlPanel) self.painter.clickedRowSignal.connect(self.updateVMDSelections) self.painter.clickedColumnSignal.connect(self.updateVMDFrame) self.updateSettings() self.updateFilters() # self.tableTest = Widget() # self.tableTest.setGeometry(100, 100, 400, 400) # self.tableTest.show() # from ..db.DbReader import read_residue_db_all # res = read_residue_db_all() # residueList = [] # 1st: name, 2nd scpolarity # for k in res: # residueList.appen([k["name"], k["scpolarity"]]) self.actionDefault.setText("Load sample data")
def __init__(self, parent, sections=[], keywords=[], entries=[], entry_keywords=[]): QSyntaxHighlighter.__init__(self, parent) self.parent = parent self.highlightingRules = [] colors = { 'knownentries': Qt.darkGreen, 'errors': Qt.red, 'allkeywords': Qt.darkMagenta, 'knownkeywords': Qt.blue, 'knownsections': Qt.darkBlue, 'teststories': Qt.darkCyan, 'storyUrls': Qt.darkMagenta, 'comments': Qt.darkYellow } try: if (hasattr(QApplication.instance(), 'is_dark_theme') and QApplication.instance().is_dark_theme): colors = { 'knownentries': Qt.green, 'errors': Qt.red, 'allkeywords': Qt.magenta, 'knownkeywords': QColor(Qt.blue).lighter(150), 'knownsections': Qt.darkCyan, 'teststories': Qt.cyan, 'storyUrls': Qt.magenta, 'comments': Qt.yellow } except Exception as e: logger.error("Failed to set dark theme highlight colors: %s" % e) if entries: # *known* entries reentries = r'(' + (r'|'.join(entries)) + r')' self.highlightingRules.append( HighlightingRule(r"\b" + reentries + r"\b", colors['knownentries'])) # true/false -- just to be nice. self.highlightingRules.append( HighlightingRule(r"\b(true|false)\b", colors['knownentries'])) # *all* keywords -- change known later. self.errorRule = HighlightingRule(r"^[^:=\s][^:=]*[:=]", colors['errors']) self.highlightingRules.append(self.errorRule) # *all* entry keywords -- change known later. reentrykeywords = r'(' + (r'|'.join( [e % r'[a-zA-Z0-9_]+' for e in entry_keywords])) + r')' self.highlightingRules.append( HighlightingRule( r"^(add_to_)?" + reentrykeywords + r"(_filelist)?\s*[:=]", colors['allkeywords'])) if entries: # separate from known entries so entry named keyword won't be masked. # *known* entry keywords reentrykeywords = r'(' + (r'|'.join( [e % reentries for e in entry_keywords])) + r')' self.highlightingRules.append( HighlightingRule( r"^(add_to_)?" + reentrykeywords + r"(_filelist)?\s*[:=]", colors['knownkeywords'])) # *known* keywords rekeywords = r'(' + (r'|'.join(keywords)) + r')' self.highlightingRules.append( HighlightingRule( r"^(add_to_)?" + rekeywords + r"(_filelist)?\s*[:=]", colors['knownkeywords'])) # *all* sections -- change known later. self.highlightingRules.append( HighlightingRule(r"^\[[^\]]+\].*?$", colors['errors'], QFont.Bold, blocknum=1)) if sections: # *known* sections resections = r'(' + (r'|'.join(sections)) + r')' resections = resections.replace('.', '\.') #escape dots. self.highlightingRules.append( HighlightingRule(r"^\[" + resections + r"\]\s*$", colors['knownsections'], QFont.Bold, blocknum=2)) # test story sections self.teststoryRule = HighlightingRule( r"^\[teststory:([0-9]+|defaults)\]", colors['teststories'], blocknum=3) self.highlightingRules.append(self.teststoryRule) # storyUrl sections self.storyUrlRule = HighlightingRule(r"^\[https?://.*\]", colors['storyUrls'], blocknum=4) self.highlightingRules.append(self.storyUrlRule) # NOT comments -- but can be custom columns, so don't flag. #self.highlightingRules.append( HighlightingRule( r"(?<!^)#[^\n]*" , colors['errors'] ) ) # comments -- comments must start from column 0. self.commentRule = HighlightingRule(r"^#[^\n]*", colors['comments']) self.highlightingRules.append(self.commentRule)
class PlaybackSlider(QSlider, EntityBinder): _default = ''' PlaybackSlider { height: 60px } PlaybackSlider::add-page, PlaybackSlider::sub-page { background: none; } PlaybackSlider::handle { margin: -4px 0px -8px 0px; } ''' _deadline_color = { TaskState.QUEUED: QColor('#a3a3a3'), TaskState.SUSPENDED: QColor('#212121'), TaskState.RENDERING: QColor('#057907'), TaskState.COMPLETED: QColor('#055679'), TaskState.FAILED: QColor('#791e05'), TaskState.PENDDING: QColor('#795c05') } _crop_size = (8, 8, 10) _bar_height = 10 _handle_width = 8 def __init__(self): super().__init__(Qt.Horizontal) self._tasks = {} self._crop_path = None self._crop_brush = None self._bar_map = None self._setup_ui() state.on_changed('crop_range', self._update) state.on_changed('loop_range', self._update) state.on_changed('Crop', self._update) state.on_changed('Loop', self._update) state.on_changed('key', self._on_key_pressed) state.on_changed('caching', self._update_progress) state.on_changed('closeup_camera', self._update_progress) def _on_key_pressed(self): if not self.isVisible(): return key = state.get('key') if key == Qt.Key_Left: self._change_slider_position(-1) elif key == Qt.Key_Right: self._change_slider_position(1) else: return def _change_slider_position(self, step): slider_position = self.sliderPosition() slider_position += step if slider_position < self.minimum(): slider_position = self.maximum() elif slider_position > self.maximum(): slider_position = self.minimum() self.setSliderPosition(slider_position) def _update(self): if not state.get('caching') and self.isVisible(): self.update() def _setup_ui(self): self.setStyleSheet(self._default) self.setFocusPolicy(Qt.NoFocus) self._create_crop_elements() self._create_bar_map() def on_entity_changed(self, entity): self.bind_entity(entity, self._update_progress, modify=False) self._update_progress() def _create_crop_elements(self): cw, ch, _ = self._crop_size path = QPainterPath() path.moveTo(0, ch) path.lineTo(cw / 2, 0) path.lineTo(cw, ch) path.lineTo(0, ch) self._crop_path = path self._crop_brush = QBrush(self.palette().light().color()) def _create_bar_map(self): self._bar_map = QPixmap(self.width(), self.height()) self._paint_progress() def resizeEvent(self, event): self._create_bar_map() def _update_progress(self): if state.get('caching') or not self.isVisible(): return progress = self._entity.get_cache_progress() if isinstance(progress, tuple): offset_tasks = {} offset_frame = state.get('offset_frame') for k, v in progress[1].items(): offset_tasks[k - offset_frame] = v self._tasks = offset_tasks self._paint_progress() self._update() def _paint_progress(self): if self._bar_map is None: return self._bar_map.fill(Qt.transparent) painter = QPainter(self._bar_map) w = self.width() hw = self._handle_width w -= hw h = self.height() if self.maximum() == 0: tw = 0 else: tw = w / self.maximum() hh = self._bar_height painter.translate(hw / 2, 0) painter.fillRect( QRect(0, (h - hh) / 2, w, hh), self.palette().dark().color() ) shot = state.get('current_shot') job = state.get('current_job') body_mode = state.get('body_mode') if shot is not None and body_mode is BodyMode.PLAYBACK: progress = self._entity.get_cache_progress() t_color = self.palette().midlight().color() c_color = QColor('#DB2A71') sf, ef = shot.frame_range closeup_camera = state.get('closeup_camera') if isinstance(progress, tuple): progress = {} progress_thumb = progress.get(CameraCacheType.THUMBNAIL, []) progress_origin = progress.get(CameraCacheType.ORIGINAL, []) is_closeup = closeup_camera and closeup_camera in progress_origin i = 0 for f in range(sf, ef + 1): if f in progress_thumb: alpha = progress_thumb[f] if alpha > 1.0: alpha = 1.0 t_color.setAlphaF(float(alpha)) painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), t_color ) if is_closeup and f in progress_origin[closeup_camera]: painter.fillRect( QRect(i * tw, (h - hh) / 2 - 2, math.ceil(tw), 2), c_color ) i += 1 elif job is not None and body_mode is BodyMode.MODEL: progress, tasks = self._entity.get_cache_progress() t_color = self.palette().midlight().color() i = 0 for f in job.frames: if f in progress: painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), t_color ) elif f in tasks: task_state = tasks[f] painter.fillRect( QRect(i * tw, (h - hh) / 2, math.ceil(tw), hh), self._deadline_color[task_state] ) i += 1 painter.end() def paintEvent(self, evt): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) w = self.width() hw = self._handle_width w -= hw h = self.height() if self.maximum() == 0: tw = 0 else: tw = w / self.maximum() # bar map painter.drawPixmap(0, 0, self._bar_map) # crop painter.translate(hw / 2, 0) body_mode = state.get('body_mode') if state.get('Crop') or state.get('Loop'): cw, ch, oh = self._crop_size clip_range = 'crop_range' if body_mode is BodyMode.MODEL: clip_range = 'loop_range' sc, ec = state.get(clip_range) if sc is not None and ec is not None: painter.fillRect( tw * sc, h - ch - oh, tw * (ec - sc), ch / 2, self.palette().base().color() ) if sc is not None: painter.fillPath( self._crop_path.translated(tw * sc - cw / 2, h - ch - oh), self._crop_brush ) if ec is not None: painter.fillPath( self._crop_path.translated(tw * ec - cw / 2, h - ch - oh), self._crop_brush ) painter.translate(-hw / 2, 0) # normal super().paintEvent(evt) frames = state.get('frames') fm = painter.fontMetrics() text = str(frames[self.value()]) width = fm.width(text) x = self.value() * tw - width / 2 + hw / 2 x_max_width = self.width() - width if x < 0: x = 0 elif x > x_max_width: x = x_max_width painter.drawText( x, 0, width, 20, Qt.AlignCenter, text )
class Pointer(QWidget): def __init__(self, gui): QWidget.__init__(self, gui) self.setObjectName('jobs_pointer') self.setVisible(False) self.resize(100, 80) self.animation = QPropertyAnimation(self, b"geometry", self) self.animation.setDuration(750) self.animation.setLoopCount(2) self.animation.setEasingCurve(QEasingCurve.Type.Linear) self.animation.finished.connect(self.hide) taily, heady = 0, 55 self.arrow_path = QPainterPath(QPointF(40, taily)) self.arrow_path.lineTo(40, heady) self.arrow_path.lineTo(20, heady) self.arrow_path.lineTo(50, self.height()) self.arrow_path.lineTo(80, heady) self.arrow_path.lineTo(60, heady) self.arrow_path.lineTo(60, taily) self.arrow_path.closeSubpath() c = self.palette().color(QPalette.ColorGroup.Active, QPalette.ColorRole.WindowText) self.color = QColor(c) self.color.setAlpha(100) self.brush = QBrush(self.color, Qt.BrushStyle.SolidPattern) # from PyQt5.Qt import QTimer # QTimer.singleShot(1000, self.start) @property def gui(self): return self.parent() def point_at(self, frac): return (self.path.pointAtPercent(frac).toPoint() - QPoint(self.rect().center().x(), self.height())) def rect_at(self, frac): return QRect(self.point_at(frac), self.size()) def abspos(self, widget): pos = widget.pos() parent = widget.parent() while parent is not self.gui: pos += parent.pos() parent = parent.parent() return pos def start(self): if config['disable_animations']: return self.setVisible(True) self.raise_() end = self.abspos(self.gui.jobs_button) end = QPointF(end.x() + self.gui.jobs_button.width()/3.0, end.y()+20) start = QPointF(end.x(), end.y() - 0.5*self.height()) self.path = QPainterPath(QPointF(start)) self.path.lineTo(end) self.path.closeSubpath() self.animation.setStartValue(self.rect_at(0.0)) self.animation.setEndValue(self.rect_at(1.0)) self.animation.setDirection(self.animation.Backward) num_keys = 100 for i in range(1, num_keys): i /= num_keys self.animation.setKeyValueAt(i, self.rect_at(i)) self.animation.start() def paintEvent(self, ev): p = QPainter(self) p.setRenderHints(p.Antialiasing) p.setBrush(self.brush) p.setPen(Qt.PenStyle.NoPen) p.drawPath(self.arrow_path) p.end()
def paintEvent(self, ev): p = QPainter(self) p.fillRect(ev.region().boundingRect(), QBrush(QColor(200, 200, 200, 220), Qt.SolidPattern)) p.end() QWebView.paintEvent(self, ev)
class Kingdom : def __init__(self, id_i, name,attribs,parent): self.id = id_i self.name = name self.attribs = attribs self.color=QColor(attribs["red"],attribs["green"],attribs["blue"],attribs["alpha"]) self.groupes = {} self.temples = [] self.parent = parent self.settings = Config().instance.settings def addGroupe (self, groupe): self.groupes[groupe.name] = groupe def addTemple (self,temple): self.temples.append(temple) def delete (self): while (len(self.groupes)!= 0): for groupe in self.groupes.values(): groupe.delete() break self.model().database._delete("gm_kingdom","ID="+str(self.id)) self.empire().kingdoms.pop(self.name) def createGroupe (self,name, default_values={}): result = self.model().database.select("ID+1","gm_groupe",False,"ID + 1 not in (select ID from gm_groupe)","ID") result.first() if 'groupe' in default_values : params = default_values['groupe'] else: params = {} params ['rank']=1 params ['description']='' params ['color']='saphir' groupe = Groupe(result.value("ID+1"), name,params,self) self.addGroupe(groupe) attribs = groupe.attribs attribs['parent']=0 attribs['name']=groupe.name attribs['ID'] = groupe.id attribs['ID_kingdom']=self.id self.model().database.insert("gm_groupe",attribs) groupe.updateFromDisk(default_values) def updateFromDisk (self,default={}): path = os.path.join(Config().instance.path_to_pic(),self.faction().name,self.empire().name) currentPath = os.path.join(path,self.name) print ('current path',currentPath) if os.path.exists(currentPath) and os.path.exists(os.path.join(currentPath,'Picture')): currentPath = os.path.join(currentPath,'Picture') list_group = list(filter(SqliteModel.isValid,os.listdir(currentPath))) #on supprime les groupe qui n existe plus list_groupe_to_delete = [] for groupe in self.groupes.values() : if (groupe.name in list_group) == False : print ('groupe demande delete',groupe.name) list_groupe_to_delete.append(groupe) for g in list_groupe_to_delete: g.delete() for groupe_name in list_group : # on met a jours les groupes existant if groupe_name in self.groupes: print ('groupe demande update',groupe_name) self.groupes[groupe_name].updateFromDisk(default) else: #on cree un nouveau groupe print ('kingodm demande delete',groupe_name) self.createGroupe(groupe_name, default) else: print ('kingdom suppresion',self.name) self.delete() # def getAllGroupes (self): # dict_groupes = {} # for groupe in self.groupes.values(): # dict_groupes[groupe.id] = groupe # if groupe.isSub() == True : # for sg in groupe.sub_groupes : # dict_groupes[sg.id] = sg # return dict_groupes # # def getAllWarriors (self): # dict_heros = {} # for groupe in self.groupes.values(): # dict_heros.update(groupe.getAllWarriors()) # if groupe.isSub() == True : # for sg in groupe.sub_groupes : # dict_heros.update(sg.getAllWarriors()) # return dict_heros def getDictAttributes (self): attribs = {} attribs['armee'] = self.attribs['armee'] attribs['description'] = self.attribs["description"] attribs['couleur'] = str(self.color.red())+','+str(self.color.green())+','+str(self.color.blue())+','+str(self.color.alpha()) attribs['name'] = self.name attribs['ID'] = self.id attribs['ID_empire'] = self.parent.id temples = None for t_id in self.attribs['temples']: if temples == None: temples=str(t_id) else: temples=temples+","+str(t_id) print ('kingdom temples',temples) attribs['temples'] = temples return attribs def getWarriorList(self, func=None): warrior_list = [] for groupe in self.groupes.values(): warrior_list+=groupe.getWarriorList(func) return warrior_list def removeGroupe(self,groupe_name): print ('groupes',self.groupes) for groupe in self.groupes.values(): if groupe.name == groupe_name: self.model().database._delete("gm_groupe","ID="+str(groupe.id)) self.groupes.pop(groupe.name) return else: for sub in groupe.sub_groupes: if sub.name == groupe_name : groupe.removeSubGroupe(sub) print ('ooo',len(groupe.sub_groupes)) if len(groupe.sub_groupes)== 0: print ('suppresion du groupe parent') self.model().database._delete("gm_groupe","ID="+str(groupe.id)) self.groupes.pop(groupe.name) return def faction (self): return self.empire().parent def model (self): return self.faction().parent def empire (self): return self.parent def findGroupeFromName(self,name): for groupe in self.groupes.values(): print ('name ;',groupe.name) if groupe.name == name: return groupe for sub in groupe.sub_groupes: if sub.name == name: return sub return None def avancement (self): warrior_list = self.getWarriorList() nb_complete = 0 nb_alive= 0 for w in warrior_list : if w.attribs['complete']==2: nb_complete +=1 if w.attribs['HP'] > 0: nb_alive += 1 return len(warrior_list),nb_complete,nb_alive
def accept(self): col = unicode(self.column_name_box.text()).strip() if not col: return self.simple_error('', _('No lookup name was provided')) if col.startswith('#'): col = col[1:] if re.match(r'^\w*$', col) is None or not col[0].isalpha() or col.lower() != col: return self.simple_error('', _('The lookup name must contain only ' 'lower case letters, digits and underscores, and start with a letter')) if col.endswith('_index'): return self.simple_error('', _('Lookup names cannot end with _index, ' 'because these names are reserved for the index of a series column.')) col_heading = unicode(self.column_heading_box.text()).strip() coldef = self.column_types[self.column_type_box.currentIndex()] col_type = coldef['datatype'] if col_type[0] == '*': col_type = col_type[1:] is_multiple = True else: is_multiple = False if not col_heading: return self.simple_error('', _('No column heading was provided')) db = self.parent.gui.library_view.model().db key = db.field_metadata.custom_field_prefix+col bad_col = False if key in self.parent.custcols: if not self.editing_col or \ self.parent.custcols[key]['colnum'] != self.orig_column_number: bad_col = True if bad_col: return self.simple_error('', _('The lookup name %s is already used')%col) bad_head = False for t in self.parent.custcols: if self.parent.custcols[t]['name'] == col_heading: if not self.editing_col or \ self.parent.custcols[t]['colnum'] != self.orig_column_number: bad_head = True for t in self.standard_colheads: if self.standard_colheads[t] == col_heading: bad_head = True if bad_head: return self.simple_error('', _('The heading %s is already used')%col_heading) display_dict = {} if col_type == 'datetime': if unicode(self.format_box.text()).strip(): display_dict = {'date_format':unicode(self.format_box.text()).strip()} else: display_dict = {'date_format': None} elif col_type == 'composite': if not unicode(self.composite_box.text()).strip(): return self.simple_error('', _('You must enter a template for' ' composite columns')) display_dict = {'composite_template':unicode(self.composite_box.text()).strip(), 'composite_sort': ['text', 'number', 'date', 'bool'] [self.composite_sort_by.currentIndex()], 'make_category': self.composite_make_category.isChecked(), 'contains_html': self.composite_contains_html.isChecked(), } elif col_type == 'enumeration': if not unicode(self.enum_box.text()).strip(): return self.simple_error('', _('You must enter at least one' ' value for enumeration columns')) l = [v.strip() for v in unicode(self.enum_box.text()).split(',') if v.strip()] l_lower = [v.lower() for v in l] for i,v in enumerate(l_lower): if v in l_lower[i+1:]: return self.simple_error('', _('The value "{0}" is in the ' 'list more than once, perhaps with different case').format(l[i])) c = unicode(self.enum_colors.text()) if c: c = [v.strip() for v in unicode(self.enum_colors.text()).split(',')] else: c = [] if len(c) != 0 and len(c) != len(l): return self.simple_error('', _('The colors box must be empty or ' 'contain the same number of items as the value box')) for tc in c: if tc not in QColor.colorNames() and not re.match("#(?:[0-9a-f]{3}){1,4}",tc,re.I): return self.simple_error('', _('The color {0} is unknown').format(tc)) display_dict = {'enum_values': l, 'enum_colors': c} elif col_type == 'text' and is_multiple: display_dict = {'is_names': self.is_names.isChecked()} elif col_type in ['int', 'float']: if unicode(self.format_box.text()).strip(): display_dict = {'number_format':unicode(self.format_box.text()).strip()} else: display_dict = {'number_format': None} elif col_type == 'comments': display_dict['heading_position'] = type(u'')(self.comments_heading_position.currentData()) display_dict['interpret_as'] = type(u'')(self.comments_type.currentData()) elif col_type == 'rating': display_dict['allow_half_stars'] = bool(self.allow_half_stars.isChecked()) if col_type in ['text', 'composite', 'enumeration'] and not is_multiple: display_dict['use_decorations'] = self.use_decorations.checkState() display_dict['description'] = self.description_box.text().strip() if not self.editing_col: self.parent.custcols[key] = { 'label':col, 'name':col_heading, 'datatype':col_type, 'display':display_dict, 'normalized':None, 'colnum':None, 'is_multiple':is_multiple, } self.parent.cc_column_key = key else: self.parent.custcols[self.orig_column_name]['label'] = col self.parent.custcols[self.orig_column_name]['name'] = col_heading self.parent.custcols[self.orig_column_name]['display'].update(display_dict) self.parent.custcols[self.orig_column_name]['*edited'] = True self.parent.custcols[self.orig_column_name]['*must_restart'] = True self.parent.cc_column_key = key QDialog.accept(self)
class Empire: def __init__ (self, id_i, name, attrib,parent): self.id = id_i self.name = name self.attrib = attrib self.attrib['icon'] = self.name+".png" self.kingdoms = {} self.color = QColor(int(self.attrib['color'].split(',')[0]),int(self.attrib['color'].split(',')[1]),int(self.attrib['color'].split(',')[2])) self.parent= parent self.geometry = self.loadGeom() def loadGeom (self): geometry = {'polygon':[]} filename = self.name+"_geometry.txt" filename = filename.lower() filename = os.path.join(Config().instance.path_to_icons(),"empire","32x32",filename) file = QFile(filename) if file.open(QIODevice.ReadOnly): stream = QTextStream(file) while (not stream.atEnd()): line = stream.readLine() if line[0]!= "#": elts = line.split(' ') l = [] print ('line',line) for i in range (1,len(elts)): try : l.append(QPoint(int(elts[i].split(',')[0]),int(elts[i].split(',')[1]))) except IndexError : qDebug("Warning : empire.loadgeom, probleme lecture paire de point") if (elts[0] == "p"): print ('add polygon') geometry['polygon'].append( l ) else: pass else : print ('not able to load file',filename) return geometry def getDictAttributes (self): attribs = {} attribs['name'] = self.name attribs['color']=str(self.color.red())+','+str(self.color.green())+','+str(self.color.blue()) attribs['icon']=self.attrib['icon'] attribs['ID']=self.id attribs['ID_faction']=self.parent.id return attribs def faction (self): return self.parent def model (self): return self.faction().parent def createKingdom (self,name, default_values = {}): result = self.model().database.select("ID+1","gm_kingdom",False,"ID + 1 not in (select ID from gm_kingdom)","ID") result.first() if 'kingdom' in default_values : params = default_values['kingdom'] else: params = {} params ['armee']='' params ['description']='' params ['red']=255 params ['green']=255 params ['blue']=0 params ['alpha']=255 params['temples']=[] kingdom = Kingdom(result.value("ID+1"), name,params,self) self.addKingdom(kingdom) attribs = kingdom.getDictAttributes() self.model().database.insert("gm_kingdom",attribs) kingdom.updateFromDisk(default_values) def delete (self): while (len(self.kingdoms)!= 0): for kingdom in self.kingdoms.values(): kingdom.delete() break self.model().database._delete("gm_empire","ID="+str(self.id)) self.faction().empires.pop(self.name) def updateFromDisk (self,default={}): path = os.path.join(Config().instance.path_to_pic(),self.faction().name) currentPath = os.path.join(path,self.name) print ('current path',currentPath) if os.path.exists(currentPath): list_kingdoms = list(filter(SqliteModel.isValid,os.listdir(currentPath))) #on supprime les groupe qui n existe plus for kingdom in self.kingdoms.values(): if (kingdom.name in list_kingdoms) == False : print ('kingodm demande delete') kingdom.delete() for kingdom_name in list_kingdoms: # on met a jours les groupes existant if kingdom_name in self.kingdoms: print ('kingodm update') self.kingdoms[kingdom_name].updateFromDisk(default) else: print ('kingodm creation') #on cree un nouveau groupe self.createKingdom(kingdom_name, default) else: self.delete() # def getAllGroupes (self): # dict_groupes = {} # for kingdom in self.kingdoms.values(): # dict_groupes.update(kingdom.getAllGroupes()) # return dict_groupes # # def getAllWarriors (self): # dict_heros= {} # for kingdom in self.kingdoms.values(): # dict_heros.update(kingdom.getAllWarriors()) # return dict_heros def addKingdom(self, kingdom): self.kingdoms[kingdom.name] = kingdom def getKingdomFromName (self,kingdom_name): for kingdom in self.kingdoms.values(): if kingdom.name == kingdom_name: return kingdom return None def getWarriorList(self,func=None): warrior_list = [] for kingdom in self.kingdoms.values(): warrior_list+=kingdom.getWarriorList(func) return warrior_list
def choose_color(self): col = QColorDialog.getColor(QColor(self._color or Qt.white), self, _('Choose a color')) if col.isValid(): self.color = unicode_type(col.name())
def ChangePenColor(self, color="black"): #改变画笔颜色 self.__penColor = QColor(color)
class RadiationDefinitionWidget(base, form): ''' Define radiation exposure for each body part ''' #Send a signal with the filename when an activity is saved. dataSaved = QtCore.pyqtSignal(object) colors = [QColor(QtCore.Qt.red),QColor(QtCore.Qt.blue),QColor(QtCore.Qt.green)] modifyingTable = False activeSources = dict() sourceKey = 1 meshLoaded = False centroidVisible = False lightsVisible = True computedFluxes = dict() def __init__(self,title='Radiation Definition',parent=None): super(base,self).__init__(parent) self.setupUi(self) self.setupZinc() lightFile = os.path.join(dir_path,"./uifiles/images/idea.png") self.showLights.setIcon(QtGui.QIcon(lightFile)) addFile = os.path.join(dir_path,"./uifiles/images/add.png") self.addSourceButton.setIcon(QtGui.QIcon(addFile)) self.removeSourceButton.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogCloseButton)) self.viewAllMesh.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogHelpButton)) axisFile = os.path.join(dir_path,"./uifiles/images/axis.png") self.showCentroid.setIcon(QtGui.QIcon(axisFile)) self._setConnections() headers = list(map(tr,['Name','Flux (kW/m^2)','Distance (m)','Latitude','Longitude','Light Color','key'])) self.sourceTable.setColumnCount(len(headers)) self.sourceTable.setHorizontalHeaderLabels(headers) self.sourceTable.horizontalHeader().setToolTip("Source beyond 10 times the mesh extant are clipped for visualization purposes") self.sourceTable.horizontalHeader().setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) for i in [1,2]: self.sourceTable.horizontalHeader().resizeSection(i,100) self.sourceTable.setItemDelegateForColumn(i,FloatDelegate(self)) self.sourceTable.horizontalHeader().resizeSection(3,100) self.sourceTable.setItemDelegateForColumn(3,FloatDelegate(self,angle=180.0)) self.sourceTable.horizontalHeader().resizeSection(4,100) self.sourceTable.setItemDelegateForColumn(4,FloatDelegate(self,angle=360.0)) self.sourceTable.horizontalHeader().resizeSection(5,75) self.sourceTable.setColumnHidden(6,True) self.sourceTable.itemChanged.connect(self.itemChanged) #To not cause QTimer error at close self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.cache = DummyCache() self.setWindowTitle(tr(title)) def setupZinc(self): self.zincContext = Context(str('Radiation')) #Zinc viewer setup self.mvLayout = QtWidgets.QVBoxLayout(self.graphicsHost) self.mvLayout.setSpacing(0) self.mvLayout.setContentsMargins(0,0,0,0) self.mvLayout.setObjectName("mvLayout") self.meshWindow = SceneviewerWidget(self.graphicsHost) self.meshWindow.setContext(self.zincContext) self.mvLayout.addWidget(self.meshWindow) self.meshWindow.graphicsInitialized.connect(self.setBackgroundColor) def setBackgroundColor(self): self.meshWindow.setBackgroundColor([1,1,1]) def setCache(self,cache): self.cache = cache def _setConnections(self): self.viewAllMesh.clicked.connect(self._viewAllMesh) self.showCentroid.clicked.connect(self._showCentroid) self.addSourceButton.clicked.connect(self._addSource) self.removeSourceButton.clicked.connect(self._removeSource) self.loadScene.clicked.connect(self._loadSceneDefinition) self.loadMesh.clicked.connect(self._loadMeshGUI) self.saveFlux.clicked.connect(self._saveRadiationModel) self.saveDefinition.clicked.connect(self._saveSceneDefinition) self.showLights.clicked.connect(self._showHideLights) def clearMesh(self): try: self.centroidVisible = False defaultRegion = self.zincContext.getDefaultRegion() if hasattr(self, 'zincGraphics'): self.zincGraphics.destroyGraphicsElements() region = defaultRegion.getFirstChild() while region.isValid(): tmp = region region = region.getNextSibling() defaultRegion.removeChild(tmp) self.setZincTitleBarString(tr("No Mesh Loaded")) self.currentMeshData = None self.meshLoaded = False self.resetMeshScaling.setEnabled(False) except: logging.debug("Failed to clear mesh") def _viewAllMesh(self): self.meshWindow.viewAll() def _showCentroid(self): self.centroidVisible = not self.centroidVisible self.centroidGraphics.setVisibilityFlag(self.centroidVisible) def _showHideLights(self): if hasattr(self.zincGraphics,'lights'): self.lightsVisible = not self.lightsVisible for lt,v in self.zincGraphics.lights.items(): v[1].setVisibilityFlag(self.lightsVisible) def _addSource(self): self.modifyingTable = True rc = self.sourceTable.rowCount() self.sourceTable.insertRow(rc) dbutton = QtWidgets.QToolButton() dbutton.setText('') qss = "background-color: %s" % self.colors[rc%3].name() dbutton.setStyleSheet(qss) dbutton.clicked.connect(self.changeColor) self.sourceTable.setItem(rc,0,QtWidgets.QTableWidgetItem('Source%d'%self.sourceKey)) self.sourceTable.setItem(rc,6,QtWidgets.QTableWidgetItem('%d'%self.sourceKey)) self.sourceKey +=1 for i in range(1,5): self.sourceTable.setItem(rc,i,QtWidgets.QTableWidgetItem('0.0')) self.sourceTable.setCellWidget(rc,5,dbutton) self.modifyingTable = False def insertSource(self,itemV): self.modifyingTable = True rc = self.sourceTable.rowCount() self.sourceTable.insertRow(rc) dbutton = QtWidgets.QToolButton() dbutton.setText('') dbutton.clicked.connect(self.changeColor) self.sourceTable.setItem(rc,0,QtWidgets.QTableWidgetItem(itemV[0])) ikey = int(itemV[-1]) self.sourceTable.setItem(rc,6,QtWidgets.QTableWidgetItem('%d'%ikey)) if self.sourceKey < ikey: self.sourceKey = ikey + 1 for i in range(1,5): self.sourceTable.setItem(rc,i,QtWidgets.QTableWidgetItem(itemV[i])) qss = "background-color: %s" % itemV[5] dbutton.setStyleSheet(qss) self.sourceTable.setCellWidget(rc,5,dbutton) self.modifyingTable = False def itemChanged(self,itm): if not self.modifyingTable: self.update() def update(self,colorChanged=False): ''' Update lights and flux ''' if not self.modifyingTable and self.meshLoaded: QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) try: self.modifyingTable = True itms = dict() for r in range(self.sourceTable.rowCount()): uset = [] for c in range(5): itm = self.sourceTable.item( r, c ) if itm is not None: uset.append(itm.text()) else: uset.append('') itm = self.sourceTable.cellWidget( r, 5 ) col = itm.palette().color(QtGui.QPalette.Button) uset.append([col.redF(),col.greenF(),col.blueF()]) itm = self.sourceTable.item( r, 6) uset.append(itm.text()) rad = float(uset[2]) lat = float(uset[3]) lon = float(uset[4]) x = rad*np.sin(lat)*np.cos(lon) y = rad*np.sin(lat)*np.sin(lon) z = rad*np.cos(lat) uset[2]=x uset[3]=y uset[4]=z itms[uset[-1]]=uset rfluxes = [] for itm in self.activeSources: if itm not in itms: rfluxes.append(itm) #Check if item has changed nfluxes = [] for itm,v in itms.items(): if itm in self.activeSources: if v==self.activeSources[itm]: continue self.activeSources[itm]=v nfluxes.append(itm) for itm in rfluxes: self.removeLightSource(itm) if itm in self.computedFluxes: del self.computedFluxes[itm] if itm in self.activeSources: del self.activeSources[itm] if not colorChanged: totalFlux = np.zeros((len(self.humanParam.faces),1)) for itm in nfluxes: self.updateLightSource(self.activeSources[itm]) v = self.activeSources[itm] flx = self.humanParam.computeIncidantFlux(float(v[1]), v[2:5]) self.computedFluxes[v[-1]] = flx*1000 #Since the input is in kilo Watt if len(self.computedFluxes)>0: for flx in self.computedFluxes.values(): totalFlux += flx totalFlux /= (len(self.computedFluxes)) self.zincGraphics.updateRadiationFluxField(totalFlux) self.radiationFlux = totalFlux self.zincGraphics.setColorBarFontColor() else: for itm in nfluxes: self.updateLightSource(self.activeSources[itm]) except Exception as e: QtWidgets.QMessageBox.critical(None,tr('Failed to update fluxes'),'%s %s'%(tr('Flux update failed'),str(e))) finally: QtWidgets.QApplication.restoreOverrideCursor() self.modifyingTable = False def updateLightSource(self,des): self.zincGraphics.createLightSource(des[-1], des[2:5], des[5], float(des[1])) def removeLightSource(self,ky): self.zincGraphics.removeLightSource(ky) def changeColor(self): but = self.sender() #index = self.table.indexAt(but.pos()) color = QtWidgets.QColorDialog.getColor(but.palette().color(1)) if color.isValid(): qss = "background-color: %s" % color.name() but.setStyleSheet(qss) self.update(True) def _removeSource(self): self.modifyingTable = True selectedItems = self.sourceTable.selectedItems() rows = set() for itm in selectedItems: rows.add(itm.row()) for r in rows: self.sourceTable.removeRow(r) self.modifyingTable = False if len(rows)>0: self.update() def _loadSceneDefinition(self): direc = self.cache.get('LASTSUCCESSFULWORKSPACE',default='.') filename = QtWidgets.QFileDialog.getOpenFileName(None, tr('Scene file'),direc,"Json (*.json)") try: if not filename is None and len(filename[0].strip()) > 0: QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) with open(filename[0],'r') as ser: result = json.load(ser) meshData = result['mesh'] tfile = tempfile.NamedTemporaryFile(suffix=".obj",delete=False) with open(tfile.name,'w') as ser: ser.write(meshData) self.computedFluxes = dict() self.sourceTable.setRowCount(0) self.activeSources.clear() self._loadMesh([tfile.name]) sources = result['sources'] for s,v in sources.items(): self.insertSource(v) self.zincGraphics.setColorBarFontColor(str('black')) self.update() tfile.close() os.remove(tfile.name) except Exception as e: QtWidgets.QMessageBox.critical(None,tr("Failed to Save"),"%s %s"%(tr("Saving failed with error"),str(e))) self.cache.set('LASTSUCCESSFULWORKSPACE',os.path.dirname(filename[0])) except Exception as e: QtWidgets.QMessageBox.critical(None, "Failed to load file", str(e)) finally: QtWidgets.QApplication.restoreOverrideCursor() def _saveRadiationModel(self): if hasattr(self, 'radiationFlux'): direc = self.cache.get('LASTSUCCESSFULWORKSPACE',default='.') filename = QtWidgets.QFileDialog.getSaveFileName(None, tr('Radiation filename'),direc,"Json (*.json)") if not filename is None and len(filename[0].strip()) > 0: with open(filename[0],'w') as ser: json.dump(self.radiationFlux.tolist(),ser) self.cache.set('LASTSUCCESSFULWORKSPACE',os.path.dirname(filename[0])) def _loadMeshGUI(self): self._loadMesh() def _loadMeshData(self,mshData): tmpfile = tempfile.NamedTemporaryFile(suffix='.obj', delete=False) with open(tmpfile.name,'w') as ser: print(mshData,file=ser) self.humanParam = HumanModel(tmpfile.name,2/3.0,True) self.humanParam.generateMesh(self.zincContext,zeroCenter=True) #Re-create with more time values when the simulation is completed self.zincGraphics = GenerateZincGraphicsElements(self.zincContext,'manequin') self.zincGraphics.createGraphicsElements() lengths = self.humanParam.bbox[0]-self.humanParam.bbox[1] self.centroidGraphics = self.zincGraphics.createCentroidGlyph(self.humanParam.centroid*0,lengths) self.zincGraphics.hideColorBar() self.centroidVisible = False self.computedFluxes = dict() self.meshLoaded = True self.currentMeshData = mshData self.update() tmpfile.close() os.remove(tmpfile.name) def _loadMesh(self,filename=None): if filename is None: direc = self.cache.get('LASTSUCCESSFULWORKSPACE',default='.') filename = QtWidgets.QFileDialog.getOpenFileName(None, tr('Load Mesh OBJ file'),direc,"OBJ (*.obj)") try: QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) QtWidgets.QApplication.processEvents() self.clearMesh() if not filename is None and len(filename[0].strip()) > 0: self.humanParam = HumanModel(filename[0],2/3.0,True) self.humanParam.generateMesh(self.zincContext,zeroCenter=True) #Re-create with more time values when the simulation is completed self.zincGraphics = GenerateZincGraphicsElements(self.zincContext,'manequin') self.zincGraphics.createGraphicsElements() lengths = self.humanParam.bbox[0]-self.humanParam.bbox[1] self.centroidGraphics = self.zincGraphics.createCentroidGlyph(self.humanParam.centroid*0,lengths) self.zincGraphics.hideColorBar() self.centroidVisible = False self.computedFluxes = dict() self.meshLoaded = True with open(filename[0],'rb') as ld: self.currentMeshData = ld.read() self.update() self.cache.set('LASTSUCCESSFULWORKSPACE',os.path.dirname(filename[0])) self.meshWindow.viewAll() except Exception as e: QtWidgets.QMessageBox.critical(None, "Failed to load file", str(e)) finally: QtWidgets.QApplication.restoreOverrideCursor() def _saveSceneDefinition(self): if self.meshLoaded: result = dict() result['mesh'] = self.currentMeshData itms = dict() for r in range(self.sourceTable.rowCount()): uset = [] for c in range(5): itm = self.sourceTable.item( r, c ) if itm is not None: uset.append(itm.text()) else: uset.append('') itm = self.sourceTable.cellWidget( r, 5 ) col = itm.palette().color(QtGui.QPalette.Button) uset.append(col.name()) itm = self.sourceTable.item( r, 6) uset.append(itm.text()) itms[uset[-1]]=uset result['sources'] = itms direc = self.cache.get('LASTSUCCESSFULWORKSPACE',default='.') filename = QtWidgets.QFileDialog.getSaveFileName(None, tr('Save scene definition'),direc,"JSON (*.json)") try: if not filename is None and len(filename[0].strip()) > 0: with open(filename[0],'w') as ser: json.dump(result,ser) except Exception as e: QtWidgets.QMessageBox.critical(None,tr("Failed to Save"),"%s %s"%(tr("Saving failed with error"),str(e)))
def hsiPlot(X): """Hyperspectral data viewer Displays the hyperspectral data. This is one of two methods to do this. Parameters ---------- X : object, Process instance The object X containing the hyperspectral array. """ app = QApplication(sys.argv) # Setting the dark-themed Fusion style for the GUI app.setStyle(QStyleFactory.create('Fusion')) dark_palette = QPalette() dark_palette.setColor(QPalette.Window, QColor(23, 23, 23)) dark_palette.setColor(QPalette.WindowText, QColor(200, 200, 200)) dark_palette.setColor(QPalette.Base, QColor(18, 18, 18)) dark_palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53)) dark_palette.setColor(QPalette.ToolTipBase, Qt.white) dark_palette.setColor(QPalette.ToolTipText, Qt.white) dark_palette.setColor(QPalette.Text, QColor(200, 200, 200)) dark_palette.setColor(QPalette.Button, QColor(33, 33, 33)) dark_palette.setColor(QPalette.ButtonText, QColor(200, 200, 200)) dark_palette.setColor(QPalette.BrightText, Qt.red) dark_palette.setColor(QPalette.Link, QColor(42, 130, 218)) dark_palette.setColor(QPalette.Highlight, QColor(42, 130, 218)) dark_palette.setColor(QPalette.HighlightedText, Qt.white) dark_palette.setColor(QPalette.Active, QPalette.Button, QColor(33, 33, 33)) dark_palette.setColor(QPalette.Disabled, QPalette.Button, QColor(20, 20, 20)) dark_palette.setColor(QPalette.Disabled, QPalette.ButtonText, QColor(120, 120, 120)) app.setPalette(dark_palette) form = HSIDialog(X) form.show() app.exec_()
def update_hover(self, hovering): cell = self.rows[0][0] if (hovering and cell.override_color is None) or ( not hovering and cell.override_color is not None): cell.override_color = QColor(Qt.red) if hovering else None self.update()
def color(color_theme, name): ans = getattr(color_theme, name) if not ans.isValid(): ans = QColor('#' + fallback_colors[name]) return ans
def decoration_for_style(palette, style, icon_size, device_pixel_ratio, is_dark): style_key = (is_dark, icon_size, device_pixel_ratio, tuple((k, style[k]) for k in sorted(style))) sentinel = object() ans = decoration_cache.get(style_key, sentinel) if ans is not sentinel: return ans ans = None kind = style.get('kind') if kind == 'color': key = 'dark' if is_dark else 'light' val = style.get(key) if val is None: which = style.get('which') val = (builtin_colors_dark if is_dark else builtin_colors_light).get(which) if val is None: val = style.get('background-color') if val is not None: ans = QColor(val) elif kind == 'decoration': which = style.get('which') if which is not None: q = builtin_decorations.get(which) if q is not None: style = q sz = int(math.ceil(icon_size * device_pixel_ratio)) canvas = QImage(sz, sz, QImage.Format.Format_ARGB32) canvas.fill(Qt.GlobalColor.transparent) canvas.setDevicePixelRatio(device_pixel_ratio) p = QPainter(canvas) p.setRenderHint(QPainter.RenderHint.Antialiasing, True) p.setPen(palette.color(QPalette.ColorRole.WindowText)) irect = QRect(0, 0, icon_size, icon_size) adjust = -2 text_rect = p.drawText( irect.adjusted(0, adjust, 0, adjust), Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop, 'a') p.drawRect(irect) fm = p.fontMetrics() pen = p.pen() if 'text-decoration-color' in style: pen.setColor(QColor(style['text-decoration-color'])) lstyle = style.get('text-decoration-style') or 'solid' q = { 'dotted': Qt.PenStyle.DotLine, 'dashed': Qt.PenStyle.DashLine, }.get(lstyle) if q is not None: pen.setStyle(q) lw = fm.lineWidth() if lstyle == 'double': lw * 2 pen.setWidth(fm.lineWidth()) q = style.get('text-decoration-line') or 'underline' pos = text_rect.bottom() height = irect.bottom() - pos if q == 'overline': pos = height elif q == 'line-through': pos = text_rect.center().y() - adjust - lw // 2 p.setPen(pen) if lstyle == 'wavy': p.drawPath(wavy_path(icon_size, height, pos)) else: p.drawLine(0, pos, irect.right(), pos) p.end() ans = QPixmap.fromImage(canvas) elif 'background-color' in style: ans = QColor(style['background-color']) decoration_cache[style_key] = ans return ans
def __init__(self, right=False, parent=None, show_open_in_editor=False): PlainTextEdit.__init__(self, parent) self.setFrameStyle(0) self.show_open_in_editor = show_open_in_editor self.side_margin = 0 self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_context_menu) self.setFocusPolicy(Qt.NoFocus) self.right = right self.setReadOnly(True) self.setLineWrapMode(self.WidgetWidth) font = self.font() ff = tprefs['editor_font_family'] if ff is None: ff = default_font_family() font.setFamily(ff) font.setPointSize(tprefs['editor_font_size']) self.setFont(font) self.calculate_metrics() self.setTabStopWidth(tprefs['editor_tab_stop_width'] * self.space_width) font = self.heading_font = QFont(self.font()) font.setPointSize(int(tprefs['editor_font_size'] * 1.5)) font.setBold(True) theme = get_theme(tprefs['editor_theme']) pal = self.palette() pal.setColor(pal.Base, theme_color(theme, 'Normal', 'bg')) pal.setColor(pal.AlternateBase, theme_color(theme, 'CursorLine', 'bg')) pal.setColor(pal.Text, theme_color(theme, 'Normal', 'fg')) pal.setColor(pal.Highlight, theme_color(theme, 'Visual', 'bg')) pal.setColor(pal.HighlightedText, theme_color(theme, 'Visual', 'fg')) self.setPalette(pal) self.viewport().setCursor(Qt.ArrowCursor) self.line_number_area = LineNumbers(self) self.blockCountChanged[int].connect(self.update_line_number_area_width) self.updateRequest.connect(self.update_line_number_area) self.line_number_palette = pal = QPalette() pal.setColor(pal.Base, theme_color(theme, 'LineNr', 'bg')) pal.setColor(pal.Text, theme_color(theme, 'LineNr', 'fg')) pal.setColor(pal.BrightText, theme_color(theme, 'LineNrC', 'fg')) self.line_number_map = LineNumberMap() self.search_header_pos = 0 self.changes, self.headers, self.images = [], [], OrderedDict() self.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOff), self.setHorizontalScrollBarPolicy( Qt.ScrollBarAlwaysOff) self.diff_backgrounds = { 'replace': theme_color(theme, 'DiffReplace', 'bg'), 'insert': theme_color(theme, 'DiffInsert', 'bg'), 'delete': theme_color(theme, 'DiffDelete', 'bg'), 'replacereplace': theme_color(theme, 'DiffReplaceReplace', 'bg'), 'boundary': QBrush(theme_color(theme, 'Normal', 'fg'), Qt.Dense7Pattern), } self.diff_foregrounds = { 'replace': theme_color(theme, 'DiffReplace', 'fg'), 'insert': theme_color(theme, 'DiffInsert', 'fg'), 'delete': theme_color(theme, 'DiffDelete', 'fg'), 'boundary': QColor(0, 0, 0, 0), } for x in ('replacereplace', 'insert', 'delete'): f = QTextCharFormat() f.setBackground(self.diff_backgrounds[x]) setattr(self, '%s_format' % x, f)
def __init__(self, parent): QWidget.__init__(self, parent) self.bcol = QColor(*gprefs['cover_grid_color']) self.btex = gprefs['cover_grid_texture'] self.update_brush() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
def __init__(self, parent, current_row, current_key, standard_colheads, standard_colnames): QDialog.__init__(self, parent) Ui_QCreateCustomColumn.__init__(self) self.setupUi(self) self.setWindowTitle(_('Create a custom column')) self.heading_label.setText(_('Create a custom column')) # Remove help icon on title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) self.setWindowIcon(icon) self.simple_error = partial(error_dialog, self, show=True, show_copy_button=False) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.shortcuts.linkActivated.connect(self.shortcut_activated) text = '<p>'+_('Quick create:') for col, name in [('isbn', _('ISBN')), ('formats', _('Formats')), ('yesno', _('Yes/No')), ('tags', _('Tags')), ('series', _('Series')), ('rating', _('Rating')), ('people', _("People's names"))]: text += ' <a href="col:%s">%s</a>,'%(col, name) text = text[:-1] self.shortcuts.setText(text) for sort_by in [_('Text'), _('Number'), _('Date'), _('Yes/No')]: self.composite_sort_by.addItem(sort_by) self.parent = parent self.parent.cc_column_key = None self.editing_col = current_row is not None self.standard_colheads = standard_colheads self.standard_colnames = standard_colnames self.column_type_box.setMaxVisibleItems(len(self.column_types)) for t in self.column_types: self.column_type_box.addItem(self.column_types[t]['text']) self.column_type_box.currentIndexChanged.connect(self.datatype_changed) all_colors = [unicode(s) for s in list(QColor.colorNames())] self.enum_colors_label.setToolTip('<p>' + ', '.join(all_colors) + '</p>') if not self.editing_col: self.datatype_changed() self.exec_() return self.setWindowTitle(_('Edit a custom column')) self.heading_label.setText(_('Edit a custom column')) self.shortcuts.setVisible(False) idx = current_row if idx < 0: self.simple_error(_('No column selected'), _('No column has been selected')) return col = current_key if col not in parent.custcols: self.simple_error('', _('Selected column is not a user-defined column')) return c = parent.custcols[col] self.column_name_box.setText(c['label']) self.column_heading_box.setText(c['name']) ct = c['datatype'] if c['is_multiple']: ct = '*' + ct self.orig_column_number = c['colnum'] self.orig_column_name = col column_numbers = dict(map(lambda x:(self.column_types[x]['datatype'], x), self.column_types)) self.column_type_box.setCurrentIndex(column_numbers[ct]) self.column_type_box.setEnabled(False) if ct == 'datetime': if c['display'].get('date_format', None): self.date_format_box.setText(c['display'].get('date_format', '')) elif ct in ['composite', '*composite']: self.composite_box.setText(c['display'].get('composite_template', '')) sb = c['display'].get('composite_sort', 'text') vals = ['text', 'number', 'date', 'bool'] if sb in vals: sb = vals.index(sb) else: sb = 0 self.composite_sort_by.setCurrentIndex(sb) self.composite_make_category.setChecked( c['display'].get('make_category', False)) self.composite_contains_html.setChecked( c['display'].get('contains_html', False)) elif ct == 'enumeration': self.enum_box.setText(','.join(c['display'].get('enum_values', []))) self.enum_colors.setText(','.join(c['display'].get('enum_colors', []))) elif ct in ['int', 'float']: if c['display'].get('number_format', None): self.number_format_box.setText(c['display'].get('number_format', '')) self.datatype_changed() if ct in ['text', 'composite', 'enumeration']: self.use_decorations.setChecked(c['display'].get('use_decorations', False)) elif ct == '*text': self.is_names.setChecked(c['display'].get('is_names', False)) self.description_box.setText(c['display'].get('description', '')) self.composite_contains_html.setToolTip('<p>' + _('If checked, this column will be displayed as HTML in ' 'book details and the content server. This can be used to ' 'construct links with the template language. For example, ' 'the template ' '<pre><big><b>{title}</b></big>' '{series:| [|}{series_index:| [|]]}</pre>' 'will create a field displaying the title in bold large ' 'characters, along with the series, for example <br>"<big><b>' 'An Oblique Approach</b></big> [Belisarius [1]]". The template ' '<pre><a href="http://www.beam-ebooks.de/ebook/{identifiers' ':select(beam)}">Beam book</a></pre> ' 'will generate a link to the book on the Beam ebooks site.') + '</p>') self.exec_()