Ejemplo n.º 1
0
    def paintColorDots(self, painter, rect):
        pen = QtGui.QPen(Qt.gray)
        pen.setStyle(Qt.SolidLine)
        painter.setPen(pen)
        scaled_pts = []
        h = rect.height()
        for point in self.points:
            x, y, r, g, b = point
            x = rect.left() + rect.width() * self.dataToX(x)
            y = rect.top() + rect.height() * (1.0 - self.alphaToY(y))
            if scaled_pts:
                painter.drawLine(scaled_pts[-1][0], scaled_pts[-1][1], x, y)
            scaled_pts.append((x, y, r, g, b))

        for x, y, r, g, b in scaled_pts:
            painter.setBrush(QtGui.QColor(255 * r, 255 * g, 255 * b))
            painter.drawEllipse(x - DOT_RADIUS, y - DOT_RADIUS, 2 * DOT_RADIUS,
                                2 * DOT_RADIUS)

        if 0 <= self.hover_point < len(scaled_pts):
            # use larger radius for hover dot
            radius = DOT_RADIUS + 2
            x, y, r, g, b = scaled_pts[self.hover_point]
            painter.setBrush(QtGui.QColor(255 * r, 255 * g, 255 * b))
            painter.drawEllipse(x - radius, y - radius, 2 * radius, 2 * radius)
Ejemplo n.º 2
0
 def set_starting_status_slot(self, component, size_download):
     """It responds to the established_connection signal emitted by the thread.
     The signal carries the file size, that will be displayed in the window."""
     # gets the graphic object that displays the status, from a dictionary previously created
     status_item_object = self.items_status_dict[component.name]# [self.status_col_idx]
     status_item_object.setText('Available: '+str(int(size_download/1048576))+' MB')
     status_item_object.setForeground(QtGui.QBrush(QtGui.QColor(204, 255, 204)))
Ejemplo n.º 3
0
    def paintHistogram(self, painter, rect):
        if self.path:
            vrange = self.original_vmax - self.original_vmin
            if vrange == 0.0:
                return
            norm_min = (self.vmin - self.original_vmin) / vrange
            norm_max = (self.vmax - self.original_vmin) / vrange
            h = rect.height() - 2
            dnorm = norm_max - norm_min
            iwidth = 1.0 / (rect.width())
            painter_path = QtGui.QPainterPath()
            for i in xrange(rect.width()):
                pos = (i * iwidth * dnorm + norm_min) * len(self.path)
                ipos = int(pos)
                if ipos < 0 or ipos >= len(self.path) - 1:
                    continue
                y0 = self.path[ipos][1]
                y1 = self.path[ipos + 1][1]
                y = y0 + (y1 - y0) * (pos - int(pos))  # lerp
                x = rect.left() + i
                y = h - self.alphaToY(y) * h + 1
                if painter_path.elementCount() == 0:
                    painter_path.moveTo(x, y)
                else:
                    painter_path.lineTo(x, y)

            pen = QtGui.QPen(Qt.red)
            pen.setStyle(Qt.SolidLine)
            painter.setPen(pen)
            painter.drawPath(painter_path)
Ejemplo n.º 4
0
 def getIcons(self):
     self.icons = {}
     # use old Tk icons
     imgDir = os.path.join(os.environ['PYMOL_DATA'], "pmg_tk/bitmaps/builder")
     imgList = glob("%s/aro*.gif" % imgDir) + glob("%s/cyc*.gif" % imgDir)
     for imgFile in imgList:
         imgName = os.path.splitext(os.path.split(imgFile)[1])[0]
         if imgName not in list(self.icons.keys()):
             image = QtGui.QImage(imgFile)
             pixmap = QtGui.QPixmap.fromImage(image)
             image.invertPixels()
             inv_pixmap = QtGui.QPixmap.fromImage(image)
             self.icons[imgName] = (QtGui.QIcon(pixmap), QtGui.QIcon(inv_pixmap))
Ejemplo n.º 5
0
def textformat(color, style=''):
    fmt = QtGui.QTextCharFormat()
    fmt.setForeground(QtGui.QColor(color))

    for word in style.split():
        if word == 'bold':
            fmt.setFontWeight(QtGui.QFont.Bold)
        elif word == 'italic':
            fmt.setFontItalic(True)
        elif word.startswith('bg:'):
            fmt.setBackground(QtGui.QColor(word[3:]))
        else:
            print('unhandled style:', word)

    return fmt
Ejemplo n.º 6
0
 def set_pmw_validator(self, validator):
     self.pmw_validator = validator
     if not self.pmw_validator:
         return None
     if self.pmw_validator["validator"] == "integer":
         self.setValidator(
             QtGui.QIntValidator(self.pmw_validator["min"],
                                 self.pmw_validator["max"]))
     elif self.pmw_validator["validator"] == "real":
         self.setValidator(
             QtGui.QDoubleValidator(self.pmw_validator["min"],
                                    self.pmw_validator["max"], 9))
     else:
         raise KeyError("Unknown 'validator': %s" %
                        self.pmw_validator["validator"])
Ejemplo n.º 7
0
    def _fill_list(self):
        """
        Create the list's data.
        """

        self.items_dict = {}

        # Checks the database log in order to obtain the date when each database was last downloaded.
        download_log_dict = {}
        if os.path.isfile(self.installer_protocol.download_log_filepath):
            with open(self.installer_protocol.download_log_filepath, "r") as l_fh:
                download_log_dict = json.loads(l_fh.read())

        # Configure the list of items is the 'all_components_list' from the PyMod Installer class.
        self.view.setRowCount(len(self.installer_protocol.components_list))
        for row_counter, component in enumerate(self.installer_protocol.components_list):
            # Create an item and set the component name as text.
            item = QtWidgets.QTableWidgetItem(component.full_name)
            # add a checkbox to the name
            item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            item.setCheckState(QtCore.Qt.Unchecked)
            # place the items in columns
            self.view.setItem(row_counter, self.component_col_idx, item)
            self.items_dict.update({component: item})


            # Set the names of the databases.
            self.view.setItem(row_counter, self.databases_col_idx, QtWidgets.QTableWidgetItem(component.databases_string))

            # Create another item displaying the status.
            graphic_status = 'Wait...'
            status = QtWidgets.QTableWidgetItem(graphic_status)
            status.setForeground(QtGui.QBrush(QtGui.QColor(191, 191, 191)))
            self.view.setItem(row_counter, self.status_col_idx, status)

            # Set the source URL.
            self.view.setItem(row_counter, self.source_col_idx, QtWidgets.QTableWidgetItem(component.remote_source))

            # Fill in the last downloaded column.
            if component.name in download_log_dict:
                last_downloaded_str = download_log_dict[component.name]
            else:
                last_downloaded_str = "Never"
            last_downloaded_item = QtWidgets.QTableWidgetItem(last_downloaded_str)
            self.view.setItem(row_counter, self.last_download_col_idx, last_downloaded_item)

            self.items_status_dict[component.name] = status
            self.items_last_download_dict[component.name] = last_downloaded_item
Ejemplo n.º 8
0
    def setup_behavior(self):
        # init input fields
        self.form.input_model.addItems(get_object_names(self.cmd))
        self.form.input_state.setValue(self.cmd.get_state())

        # select pk1 atom if available
        self.update_from_pk1()

        # Install an eventfilter
        self.form.treeWidget.installEventFilter(self)

        # hook up events
        self.form.input_model.currentIndexChanged.connect(
            self.update_treewidget_model)
        self.form.input_state.valueChanged.connect(
            self.update_treewidget_state)
        self.form.input_index.valueChanged.connect(self.update_treewidget)
        self.form.button_refresh.clicked.connect(self.update_model_list)

        # themed icons only available by default on X11
        if self.form.button_refresh.icon().isNull():
            self.form.button_refresh.setIcon(
                QtGui.QIcon(
                    os.path.expandvars(
                        '$PYMOL_DATA/pmg_qt/icons/refresh.svg')))

        # update and show
        self.update_treewidget_model()
        self.form.treeWidget.setColumnWidth(0, 200)

        self.form.treeWidget.itemChanged.connect(self.item_changed)
Ejemplo n.º 9
0
    def __init__(self, parent, cmd):
        QtWidgets.QWidget.__init__(self, parent, Qt.Window)
        self.setMinimumSize(400, 500)
        self.cmd = cmd

        self.model = QtGui.QStandardItemModel(self)
        self.proxy_model = QtCoreModels.QSortFilterProxyModel(self)
        self.proxy_model.setSourceModel(self.model)

        self.setWindowTitle('PyMOL Advanced Settings')
        layout = QtWidgets.QVBoxLayout(self)
        self.setLayout(layout)
        self.filter_le = QtWidgets.QLineEdit(self)
        layout.addWidget(self.filter_le)
        self.filter_le.setPlaceholderText("Filter")
        self.filter_le.textChanged.connect(self.proxy_model.setFilterRegExp)

        self.populateData()

        self.table = QtWidgets.QTableView(self)
        self.table.setModel(self.proxy_model)
        layout.addWidget(self.table)

        self.formatTable()

        self.model.itemChanged.connect(self.itemChanged)
Ejemplo n.º 10
0
    def __init__(self, parent):
        self.gui = parent
        self.fb_scale = 1.0

        # OpenGL context setup
        if USE_QOPENGLWIDGET:
            f = QtGui.QSurfaceFormat()
        else:
            f = QtOpenGL.QGLFormat()

        from pymol.invocation import options

        # logic equivalent to layer5/main.cpp:launch

        if options.multisample:
            f.setSamples(4)

        if options.force_stereo != -1:
            # See layer1/Setting.h for stereo modes

            if options.stereo_mode in (1, 12) or (
                    options.stereo_mode == 0 and AUTO_DETECT_STEREO):
                f.setStereo(True)

            if options.stereo_mode in (11, 12) and not USE_QOPENGLWIDGET:
                f.setAccum(True)

        if USE_QOPENGLWIDGET:
            super(PyMOLGLWidget, self).__init__(parent=parent)
            self.setFormat(f)
            self.setUpdateBehavior(QtWidgets.QOpenGLWidget.PartialUpdate)
        else:
            super(PyMOLGLWidget, self).__init__(f, parent=parent)

        # pymol instance
        self.pymol = PyMOL()
        self.pymol.start()
        self.cmd = self.pymol.cmd

        # capture python output for feedback
        import pcatch
        pcatch._install()

        # for passive move drag
        self.setMouseTracking(True)

        # for accepting keyboard input (command line, shortcuts)
        self.setFocusPolicy(Qt.ClickFocus)

        # for idle rendering
        self._timer = QtCore.QTimer()
        self._timer.setSingleShot(True)
        self._timer.timeout.connect(self._pymolProcess)

        # drag n drop
        self.setAcceptDrops(True)

        # pinch-zoom
        self.grabGesture(Qt.PinchGesture)
Ejemplo n.º 11
0
 def update_treeview():
     model.clear()
     for key in manager.get_keys():
         item = QtGui.QStandardItem()
         item.setText(key)
         model.blockSignals(True)
         model.appendRow(item)
         model.blockSignals(False)
Ejemplo n.º 12
0
    def create_little_canvas(self,
                             hit,
                             domain_hit,
                             default_width=300,
                             default_height=11):

        # Builds the graphics view and scene.
        canvas_plot_scene = QtWidgets.QGraphicsScene()
        canvas_plot_view = QtWidgets.QGraphicsView(canvas_plot_scene)
        canvas_plot_view.setFixedHeight(default_height)
        canvas_plot_view.setFixedWidth(default_width)
        canvas_plot_view.setSizePolicy(self.preferred_size_policy)
        canvas_plot_view.setHorizontalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOff)
        canvas_plot_view.setVerticalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOff)
        canvas_plot_view.setFrameShape(QtWidgets.QFrame.NoFrame)
        canvas_plot_view.setStyleSheet("border: 0px; background: %s" %
                                       self.view_bg_color)

        # Get the coordinates of the various graphics elements.
        one_res_span = default_width / float(
            self.query_len
        )  # proporzione tra la lunghezza della seq e lo spazio grafico
        queryspan_start = int(domain_hit['start'])
        queryspan_end = int(domain_hit['end'])
        queryspan_start_graphic = int(queryspan_start * one_res_span)
        queryspan_end_graphic = int(queryspan_end * one_res_span)
        # canvas_true_width = int(queryspan_end_graphic-queryspan_start_graphic)
        # space_at_end = int(int(default_width)-(canvas_true_width+queryspan_start_graphic))

        # Draws a gray rectangle representing the full protein sequence.
        canvas_plot_scene.addRect(0, 3, default_width, 5, self.full_seq_pen,
                                  self.full_seq_brush)

        # Draws a colored rectangle representing the domain.
        line_pen = QtGui.QPen(QtGui.QColor(0, 0, 0, 255), 1)
        qcolor = QtGui.QColor(0, 0, 0)
        qcolor.setNamedColor(hit['dom_color_hex'])
        brush = QtGui.QBrush(qcolor)
        canvas_plot_scene.addRect(
            queryspan_start_graphic, 0,
            queryspan_end_graphic - queryspan_start_graphic, default_height,
            line_pen, brush)

        return canvas_plot_view
Ejemplo n.º 13
0
def make_pymol_qicon():
    icons_dir = os.path.expandvars('$PYMOL_DATA/pymol/icons')
    icon = QtGui.QIcon()

    for size in (16, 32, 128):
        icon.addFile(os.path.join(icons_dir, 'icon2_%dx%d.png' % (size, size)),
                     QtCore.QSize(size, size))

    return icon
Ejemplo n.º 14
0
 def get_available_fonts(self):
     # Get the system fonts.
     font_family_list = [font_name.lower() for font_name in QtGui.QFontDatabase().families()]
     # Get the fonts available in PyMod.
     selected_fonts = [font_name.lower() for font_name in self.selected_fonts_dict.get(sys.platform, [])]
     # Filter the system fonts list.
     font_family_list = [font_name for font_name in font_family_list if font_name in selected_fonts]
     font_family_list.insert(0, "courier new")
     font_family_list.sort()
     return font_family_list
Ejemplo n.º 15
0
 def _get_scene_png(self, scene_name):
     '''
     Returns a QPixmap object that can be assigned to a label
     in order to display the scene thumbnail.
     This will be obsolete and removed in the future.
     '''
     scene_pix_map = QtGui.QPixmap()
     png_buf = self.cmd.get_scene_thumbnail(scene_name)
     scene_pix_map.loadFromData(png_buf, "PNG")
     return scene_pix_map
Ejemplo n.º 16
0
 def set_update_status_slot(self, component, text="new status", color="light_green"):
     status_item_object = self.items_status_dict[component.name]
     status_item_object.setText(text)
     if color == "light_green":
         status_item_object.setForeground(QtGui.QBrush(QtGui.QColor(204, 255, 204)))
     elif color == "green":
         status_item_object.setForeground(QtGui.QBrush(QtGui.QColor(10, 255, 10)))
     elif color == "gray":
         status_item_object.setForeground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
     elif color == "red":
         status_item_object.setForeground(QtGui.QBrush(QtGui.QColor(255, 0, 0)))
     else:
         raise KeyError(color)
Ejemplo n.º 17
0
 def paintValueBox(self,
                   painter,
                   font_metrics,
                   x,
                   y,
                   right_just,
                   value,
                   format="%.3f"):
     s = format % value
     sw = font_metrics.width(s)
     sh = font_metrics.height()
     if right_just:
         rect = QtCore.QRect(x - sw - 4, y - sh, sw + 4, sh + 2)
     else:
         rect = QtCore.QRect(x, y - sh, sw + 4, sh + 2)
     painter.fillRect(rect,
             QtGui.QColor(96, 96, 128) if self.line_color == Qt.lightGray else
             QtGui.QColor(0xFF, 0xFF, 0xFF))
     painter.drawRect(rect)
     painter.drawText(rect.x() + 2, y - 2, s)
     return rect
Ejemplo n.º 18
0
    def add_domain_representation(self, hit, domain_hit):

        queryspan_start = int(domain_hit['start'])
        queryspan_end = int(domain_hit['end'])
        domain_x = self.x_init + int(
            queryspan_start / float(self.query_len) * self.full_seq_rect_w)
        domain_y = self.domain_y_init
        domain_w = int((queryspan_end - queryspan_start) /
                       float(self.query_len) * self.full_seq_rect_w)
        domain_h = 25

        domain_pen = QtGui.QPen(QtGui.QColor(0, 0, 0, 255), 1)
        qcolor = QtGui.QColor(0, 0, 0)
        qcolor.setNamedColor(hit['dom_color_hex'])
        domain_brush = QtGui.QBrush(qcolor)

        domain_rect = self.canvas_plot_scene.addRect(domain_x, domain_y,
                                                     domain_w, domain_h,
                                                     domain_pen, domain_brush)
        domain_rect.setVisible(False)

        return domain_rect
Ejemplo n.º 19
0
 def add_text_to_canvas(x,
                        y,
                        text,
                        anchor=None,
                        font_color="black",
                        font_size=6,
                        html_font_size=10):
     _text = str(text)
     text_item = self.canvas_plot_scene.addText(_text)
     w = text_item.boundingRect().width()
     h = text_item.boundingRect().height()
     text_item.setPos(int(x - w / 2.5), int(y - h / 2.5))
     text_item.setFont(QtGui.QFont(text_item.font().family(),
                                   font_size))
Ejemplo n.º 20
0
    def paintAxes(self, painter, rect):
        low = int(math.ceil(self.vmin))
        hi = int(math.floor(self.vmax)) + 1
        pen = painter.pen()
        pen.setStyle(Qt.SolidLine)
        pen.setColor(self.line_color)
        painter.setPen(pen)
        fm = QtGui.QFontMetrics(painter.font())
        fw = fm.averageCharWidth()
        fh = fm.height() - 2
        x0 = rect.left()
        x1 = rect.right()
        y0 = rect.bottom()
        y1 = y0 + 4
        lastx = x0

        # horizontal axis
        for tick in range(low, hi):
            s = str(tick)
            w = fw * len(s)
            x = x0 + w / 2 + rect.width() * (
                tick - self.vmin) / float(self.vmax - self.vmin)
            if x - lastx > w + 2 * fw:
                painter.drawLine(x, y0, x, y1)
                painter.drawText(x - w / 2, y1 + fh - 2, s)
                lastx = x

        #vertical axis
        x1 = rect.left()
        lasty = y0
        for tick in range(1, 10):
            t = tick / 10.0
            y = y0 - self.alphaToY(t) * rect.height()
            if lasty - y > fh and y > 2 * fh:
                painter.drawLine(x1 - 5, y, x1, y)
                painter.drawText(x1 - 5 - 3 * fw, y - 2 + fh / 2, str(t))
                lasty = y

        # text boxes
        self.text_boxes["vmin"] = self.paintValueBox(painter, fm, rect.left(),
                                                     y1 + fh, False, self.vmin)
        self.text_boxes["vmax"] = self.paintValueBox(painter, fm, rect.right(),
                                                     y1 + fh, True, self.vmax)
        self.text_boxes["amax"] = self.paintValueBox(painter,
                                                     fm,
                                                     x0 - 4 * fw,
                                                     2 + fh,
                                                     False,
                                                     self.amax,
                                                     format="%.2f")
Ejemplo n.º 21
0
    def __init__(self, parent=None, filename='', title='Text Editor'):
        super(TextEditor, self).__init__()

        self.highlight = None

        self.root = self
        self.root.setWindowTitle(title)

        menubar = self.root.menuBar()
        filemenu = menubar.addMenu("File")
        filemenu.addAction("Open", self.doOpen, QtGui.QKeySequence("Ctrl+O"))
        filemenu.addAction("Save", self.doSave, QtGui.QKeySequence("Ctrl+S"))
        filemenu.addAction("Save as ...", self.doSaveAs,
                           QtGui.QKeySequence("Ctrl+Shift+S"))

        syntaxmenu = menubar.addMenu("Syntax")
        syntaxgroup = QtWidgets.QActionGroup(self)
        self.syntaxactions = {}

        for label in ['Python', 'PML', 'Plain Text']:
            key = label.split()[0].lower()
            action = syntaxmenu.addAction(label,
                                          lambda t=key: self.setSyntax(t))
            syntaxgroup.addAction(action)
            action.setCheckable(True)
            self.syntaxactions[key] = action

        self.text = QtWidgets.QPlainTextEdit()
        self.text.setFont(getMonospaceFont())
        self.root.setCentralWidget(self.text)

        connectFontContextMenu(self.text)

        self._open(filename)

        self.root.show()
        self.root.raise_()
Ejemplo n.º 22
0
def _copy_image(_self=pymol.cmd, quiet=1, dpi=-1):
    import tempfile
    fname = tempfile.mktemp('.png')

    if not _self.png(fname, prior=1, dpi=dpi):
        print("no prior image")
        return

    try:
        qim = QtGui.QImage(fname)
        QtWidgets.QApplication.clipboard().setImage(qim)
    finally:
        os.unlink(fname)

    if not quiet:
        print(" Image copied to clipboard")
Ejemplo n.º 23
0
 def setPointColor(self, point, triple):
     """
     Opens color picker and sets color of one or three points.
     """
     self.color_point = point
     self.color_triple = triple
     _, _, r, g, b = self.points[self.color_point]
     if not self.color_dialog:
         self.color_dialog = QtWidgets.QColorDialog(self)
         self.color_dialog.currentColorChanged.connect(
             self.updatePointColor)
         self.color_dialog.finished.connect(self.colorDialogClosed)
     self.original_color = QtGui.QColor(255 * r, 255 * g, 255 * b)
     self.color_dialog.setCurrentColor(self.original_color)
     # open modal color dialog
     self.color_dialog.open()
Ejemplo n.º 24
0
 def paintGrid(self, painter, rect):
     pen = QtGui.QPen(self.line_color)
     painter.setPen(pen)
     x0 = rect.x()
     x1 = rect.x() + rect.width()
     y0 = rect.y()
     y1 = rect.y() + rect.height()
     painter.drawLine(x0, y1, x1, y1)
     painter.drawLine(x0, y0, x0, y1)
     h = rect.height()
     num_lines = 10
     pen.setStyle(Qt.DashLine)
     painter.setPen(pen)
     for line in xrange(1, num_lines):
         y = y0 + h * (1.0 - self.alphaToY(line / float(num_lines)))
         painter.drawLine(x0, y, x1, y)
Ejemplo n.º 25
0
    def __init__(self,
                 i,
                 j,
                 tags,
                 mark_size,
                 parent_window,
                 pen=None,
                 brush=None):

        # Build the polygon object representing a triangle.
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            polygon = QtGui.QPolygonF([
                QtCore.QPoint(i, j - 2 * mark_size),
                QtCore.QPoint(i - 1.7 * mark_size, j + mark_size),
                QtCore.QPoint(i + 1.7 * mark_size, j + mark_size)
            ])
        # Initialize.
        super(Ramachandran_plot_triangle, self).__init__(polygon)
        self.common_initialization(i, j, tags, parent_window, pen, brush)
Ejemplo n.º 26
0
    def paintEvent(self, event):
        """
        Paints the editor widget.
        """
        painter = QtGui.QPainter()
        self.paint_rect = event.rect()
        self.paint_rect.adjust(self.left_margin, 0, 0, -self.bottom_margin)

        # tweak color depening on the panel floating state
        # disabled: always use default style
        is_floating = True  # self.parent().parent().isFloating()
        self.line_color = Qt.darkGray if is_floating else Qt.lightGray

        painter.begin(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        self.paintGrid(painter, self.paint_rect)
        self.paintAxes(painter, self.paint_rect)
        painter.setClipRect(self.paint_rect)
        self.paintHistogram(painter, self.paint_rect)
        self.paintZoomArea(painter, self.paint_rect)
        painter.setClipping(False)
        self.paintColorDots(painter, self.paint_rect)
        painter.end()
Ejemplo n.º 27
0
    def __init__(self,
                 data,
                 parent,
                 sortable=False,
                 column_labels=None,
                 row_labels=None,
                 row_labels_height=25,
                 *args):

        self.data = data
        self.column_labels = column_labels
        self.row_labels = row_labels
        self.row_labels_height = row_labels_height

        # Get a set with the length of each column.
        rows_number = len(self.data)
        columns_number = len(self.data[0])

        QtWidgets.QTableWidget.__init__(self,
                                        parent=parent,
                                        columnCount=columns_number,
                                        rowCount=rows_number,
                                        sortingEnabled=sortable,
                                        *args)

        self.set_data()
        self.resizeColumnsToContents()
        # self.resizeRowsToContents()

        self.setStyleSheet(
            "QTableView::item {border: 0px; padding: 0px; margin: 0px;}")
        # self.itemDoubleClicked.connect(self.on_click)

        default_font = QtGui.QFont()
        default_font.setPointSize(default_font.pointSize() - 1)
        self.setFont(default_font)
Ejemplo n.º 28
0
 def paintZoomArea(self, painter, rect):
     if self.init_pos and self.zoom_pos:
         rect.setLeft(self.init_pos.x())
         rect.setRight(self.zoom_pos.x())
         painter.fillRect(rect, QtGui.QBrush(QtGui.QColor(0, 64, 128, 128)))
Ejemplo n.º 29
0
    def build_plotting_area(self,
                            use_controls=True,
                            use_all_controls_buttons=True,
                            messagebar_initial_text=None,
                            update_messagebar=False,
                            messagebar_text_on_update="",
                            messagebar_vars_on_update=(),
                            on_click_action=None,
                            x_label_text="x",
                            y_label_text="y",
                            label_size=None,
                            use_save_to_csv=True,
                            hide_x_ticks=False,
                            hide_y_ticks=False,
                            # hide_x_label=False,
                            # hide_y_label=False,
                            highlight_points=True,
                            ):
        """
        Configures the plotting area of the window.

        # Arguments
            use_controls: adds to the plotting window a right column with checkbuttons
                to show/hide the lines plots in the drawing area.
            use_all_controls_buttons: adds to the plotting control column 'Show All'
                and 'Hide All' buttons.
            messagebar_initial_text: initial text to be displayed in the messagebar
                of the plotting window.
            update_messagebar: if 'True', the messagebar will be updated when clicking
                some point of the scatterplots.
            messagebar_text_on_update: text to be shown when the messagebar is update.
                If it contains the "__plot_name__", "__x__", "__y__" string, they
                will be substituted with the name of the plot, the x value and y value
                of the point respectively. If some 'additional_data' is provided
                for a plot, its data will also be used to update the messagebar.
                Each element of an 'additional_data' list has to correspond to a
                data point of a plot and must be a dictionary in which the keys are
                strings representing the names of the additional data series. If,
                for example, these dictionaries have a key named 'info' and if the
                'messagebar_text_on_update' contains the string "__info__", it will
                be substituted with the value associated to the 'info' key of that
                'additional_data' point.
            on_click_action: function to be called when a point of a scatterplot
                is clicked. This function must have the following argument:
                    point_data: a dictionary with additional data for the point
                        or a 'None' value.
            x_label_text: text for the x-axis label.
            y_label_text: text for the y-axis label.
            label_size: font size for the axis labels.
            use_save_to_csv: if 'True' add to the plotting window menu a command
                to save data in the csv format.
            hide_x_ticks: if 'True', hide the ticks and numbers of the x-axis.
            hide_y_ticks: if 'True', hide the ticks and numbers of the y-axis.
            highlight_points: if 'True', the scatterplot points will be highlighted
                when they are clicked with the mouse.

        """

        # Stores the arguments.
        self.use_controls = use_controls
        if self.use_controls:
            self.upper_frame_layout.addWidget(self.info_frame, 0, 0)

            self.middle_splitter.addWidget(self.plot_frame)
            self.middle_splitter.addWidget(self.controls_scrollarea)
            self.upper_frame_layout.addWidget(self.middle_splitter, 1, 0)

            self.controls_scrollarea.resize(230, self.controls_scrollarea.sizeHint().height())
            self.controls_frame_layout.addWidget(self.labels_title, 0, 0, 1, 2)

            self.lower_frame_layout.addWidget(self.on_click_label, 0, 2)
            self.lower_frame_layout.addWidget(self.interact_button, 0, 3)
            self.lower_frame_layout.addWidget(self.no_interaction_button, 0, 4)
        else:
            self.upper_frame_layout.addWidget(self.plot_frame, 0, 0)


        self.use_all_controls_buttons = use_all_controls_buttons
        if self.use_controls and self.use_all_controls_buttons:
            self.lower_frame_layout.addWidget(self.show_label, 0, 5)
            self.lower_frame_layout.addWidget(self.show_all_button, 0, 6)
            self.lower_frame_layout.addWidget(self.hide_all_button, 0, 7)

        self.messagebar_initial_text = messagebar_initial_text
        if self.messagebar_initial_text is not None:
            self.info_label.setText(self.messagebar_initial_text)

        self.update_messagebar = update_messagebar
        self.on_click_action = on_click_action
        if self.on_click_action is not None:
            if not hasattr(self.on_click_action, "__call__"):
                raise TypeError("'on_click_action' must be a function.")
        self.messagebar_text_on_update = messagebar_text_on_update
        self.messagebar_vars_on_update = messagebar_vars_on_update

        self.use_save_to_csv = use_save_to_csv
        if self.use_save_to_csv:
            self.file_menu.addAction(self.save_to_csv_action)
        self.file_menu.addAction(self.save_to_png_action)

        self.highlight_points = highlight_points


        # Configure the PlotWidget.
        self.graphWidget.setMenuEnabled(False)

        if label_size is not None:
            kwargs = {"font-size": "%spx" % label_size}
            font = QtGui.QFont()
            font.setPixelSize(label_size)
            # curve_pen = pyqtgraph.mkPen(width=2, color="r") # Color and width of the curve.
        else:
            kwargs = {}

        self.graphWidget.setLabel("left", y_label_text, **kwargs)
        self.graphWidget.setLabel("bottom", x_label_text, **kwargs)

        if label_size is not None:
            self.graphWidget.getAxis("left").tickFont = font
            self.graphWidget.getAxis("bottom").tickFont = font
            # self.graphWidget.getAxis("left").setPen(curve_pen)

        if hide_x_ticks:
            self.graphWidget.getAxis("bottom").setStyle(showValues=False, tickLength=0)
        if hide_y_ticks:
            self.graphWidget.getAxis("left").setStyle(showValues=False, tickLength=0)

        if self.on_click_action is not None:
            self.graphWidget.getViewBox().scene().sigMouseClicked.connect(self.on_scene_click)
Ejemplo n.º 30
0
    def __init__(self):  # noqa
        QtWidgets.QMainWindow.__init__(self)
        self.setDockOptions(QtWidgets.QMainWindow.AllowTabbedDocks
                            | QtWidgets.QMainWindow.AllowNestedDocks)

        # resize Window before it is shown
        options = pymol.invocation.options
        self.resize(options.win_x + (220 if options.internal_gui else 0),
                    options.win_y + (246 if options.external_gui else 18))

        # for thread-safe viewport command
        self.viewportsignal.connect(self.pymolviewport)

        # reusable dialogs
        self.dialog_png = None
        self.advanced_settings_dialog = None
        self.props_dialog = None
        self.builder = None

        # setting index -> callable
        self.setting_callbacks = defaultdict(list)

        # "session_file" setting in window title
        self.setting_callbacks[440].append(lambda v: self.setWindowTitle(
            "PyMOL (" + os.path.basename(v) + ")"))

        # "External" Command Line and Loggin Widget
        self._setup_history()
        self.lineedit = CommandLineEdit()
        self.lineedit.setObjectName("command_line")
        self.browser = QtWidgets.QPlainTextEdit()
        self.browser.setObjectName("feedback_browser")
        self.browser.setReadOnly(True)

        # convenience: clicking into feedback browser gives focus to command
        # line. Drawback: Copying with CTRL+C doesn't work in feedback
        # browser -> clear focus proxy while text selected
        self.browser.setFocusProxy(self.lineedit)

        @self.browser.copyAvailable.connect
        def _(yes):
            self.browser.setFocusProxy(None if yes else self.lineedit)
            self.browser.setFocus()

        # Font
        self.browser.setFont(getMonospaceFont())
        connectFontContextMenu(self.browser)

        lineeditlayout = QtWidgets.QHBoxLayout()
        command_label = QtWidgets.QLabel("PyMOL>")
        command_label.setObjectName("command_label")
        lineeditlayout.addWidget(command_label)
        lineeditlayout.addWidget(self.lineedit)
        self.lineedit.setToolTip('''Command Input Area

Get the list of commands by hitting <TAB>

Get the list of arguments for one command with a question mark:
PyMOL> color ?

Read the online help for a command with "help":
PyMOL> help color

Get autocompletion for many arguments by hitting <TAB>
PyMOL> color ye<TAB>    (will autocomplete "yellow")
''')

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addLayout(lineeditlayout)

        quickbuttonslayout = QtWidgets.QVBoxLayout()
        quickbuttonslayout.setSpacing(2)

        extguilayout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.LeftToRight)
        extguilayout.setContentsMargins(2, 2, 2, 2)
        extguilayout.addLayout(layout)
        extguilayout.addLayout(quickbuttonslayout)

        class ExtGuiFrame(QtWidgets.QFrame):
            def mouseDoubleClickEvent(_, event):
                self.toggle_ext_window_dockable(True)

            _size_hint = QtCore.QSize(options.win_x, options.ext_y)

            def sizeHint(self):
                return self._size_hint

        dockWidgetContents = ExtGuiFrame(self)
        dockWidgetContents.setLayout(extguilayout)
        dockWidgetContents.setObjectName("extgui")

        self.ext_window = \
            dockWidget = QtWidgets.QDockWidget(self)
        dockWidget.setWindowTitle("External GUI")
        dockWidget.setWidget(dockWidgetContents)
        if options.external_gui:
            dockWidget.setTitleBarWidget(QtWidgets.QWidget())
        else:
            dockWidget.hide()

        self.addDockWidget(Qt.TopDockWidgetArea, dockWidget)

        # rearrange vertically if docking left or right
        @dockWidget.dockLocationChanged.connect
        def _(area):
            if area == Qt.LeftDockWidgetArea or area == Qt.RightDockWidgetArea:
                extguilayout.setDirection(QtWidgets.QBoxLayout.BottomToTop)
                quickbuttonslayout.takeAt(quickbuttons_stretch_index)
            else:
                extguilayout.setDirection(QtWidgets.QBoxLayout.LeftToRight)
                if quickbuttons_stretch_index >= quickbuttonslayout.count():
                    quickbuttonslayout.addStretch()

        # OpenGL Widget
        self.pymolwidget = PyMOLGLWidget(self)
        self.setCentralWidget(self.pymolwidget)

        cmd = self.cmd = self.pymolwidget.cmd
        '''
        # command completion
        completer = QtWidgets.QCompleter(cmd.kwhash.keywords, self)
        self.lineedit.setCompleter(completer)
        '''

        # overload <Tab> action
        self.lineedit.installEventFilter(self)
        self.pymolwidget.installEventFilter(self)

        # Quick Buttons
        for row in [
            [
                ('Reset', cmd.reset),
                ('Zoom', lambda: cmd.zoom(animate=1.0)),
                ('Orient', lambda: cmd.orient(animate=1.0)),

                # render dialog will be constructed when the menu is shown
                # for the first time. This way it's populated with the current
                # viewport and settings. Also defers parsing of the ui file.
                ('Draw/Ray', WidgetMenu(self).setSetupUi(self.render_dialog)),
            ],
            [
                ('Unpick', cmd.unpick),
                ('Deselect', cmd.deselect),
                ('Rock', cmd.rock),
                ('Get View', self.get_view),
            ],
            [
                ('|<', cmd.rewind),
                ('<', cmd.backward),
                ('Stop', cmd.mstop),
                ('Play', cmd.mplay),
                ('>', cmd.forward),
                ('>|', cmd.ending),
                ('MClear', cmd.mclear),
            ],
            [
                ('Builder', self.open_builder_panel),
                ('Properties', self.open_props_dialog),
                ('Rebuild', cmd.rebuild),
            ],
        ]:
            hbox = QtWidgets.QHBoxLayout()
            hbox.setSpacing(2)

            for name, callback in row:
                btn = QtWidgets.QPushButton(name)
                btn.setProperty("quickbutton", True)
                btn.setAttribute(Qt.WA_LayoutUsesWidgetRect)  # OS X workaround
                hbox.addWidget(btn)

                if callback is None:
                    btn.setEnabled(False)
                elif isinstance(callback, QtWidgets.QMenu):
                    btn.setMenu(callback)
                else:
                    btn.released.connect(callback)

            quickbuttonslayout.addLayout(hbox)

        # progress bar
        hbox = QtWidgets.QHBoxLayout()
        self.progressbar = QtWidgets.QProgressBar()
        self.progressbar.setSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                       QtWidgets.QSizePolicy.Minimum)
        hbox.addWidget(self.progressbar)
        self.abortbutton = QtWidgets.QPushButton('Abort')
        self.abortbutton.setStyleSheet("background: #FF0000; color: #FFFFFF")
        self.abortbutton.released.connect(cmd.interrupt)
        hbox.addWidget(self.abortbutton)
        quickbuttonslayout.addLayout(hbox)

        quickbuttonslayout.addStretch()
        quickbuttons_stretch_index = quickbuttonslayout.count() - 1

        # menu top level
        self.menubar = menubar = self.menuBar()

        # action groups
        actiongroups = {}

        def _addmenu(data, menu):
            '''Fill a menu from "data"'''
            menu.setTearOffEnabled(True)
            menu.setWindowTitle(menu.title())  # needed for Windows
            for item in data:
                if item[0] == 'separator':
                    menu.addSeparator()
                elif item[0] == 'menu':
                    _addmenu(item[2], menu.addMenu(item[1].replace('&', '&&')))
                elif item[0] == 'command':
                    command = item[2]
                    if command is None:
                        print('warning: skipping', item)
                    else:
                        if isinstance(command, str):
                            command = lambda c=command: cmd.do(c)
                        menu.addAction(item[1], command)
                elif item[0] == 'check':
                    if len(item) > 4:
                        menu.addAction(
                            SettingAction(self, cmd, item[2], item[1], item[3],
                                          item[4]))
                    else:
                        menu.addAction(
                            SettingAction(self, cmd, item[2], item[1]))
                elif item[0] == 'radio':
                    label, name, value = item[1:4]
                    try:
                        group, type_, values = actiongroups[item[2]]
                    except KeyError:
                        group = QtWidgets.QActionGroup(self)
                        type_, values = cmd.get_setting_tuple(name)
                        actiongroups[item[2]] = group, type_, values
                    action = QtWidgets.QAction(label, self)
                    action.triggered.connect(lambda _=0, args=(name, value):
                                             cmd.set(*args, log=1, quiet=0))

                    self.setting_callbacks[cmd.setting._get_index(
                        name)].append(
                            lambda v, V=value, a=action: a.setChecked(v == V))

                    group.addAction(action)
                    menu.addAction(action)
                    action.setCheckable(True)
                    if values[0] == value:
                        action.setChecked(True)
                elif item[0] == 'open_recent_menu':
                    self.open_recent_menu = menu.addMenu('Open Recent...')
                else:
                    print('error:', item)

        # recent files menu
        self.open_recent_menu = None

        # for plugins
        self.menudict = {'': menubar}

        # menu
        for _, label, data in self.get_menudata(cmd):
            assert _ == 'menu'
            menu = menubar.addMenu(label)
            self.menudict[label] = menu
            _addmenu(data, menu)

        # hack for macOS to hide "Edit > Start Dictation"
        # https://bugreports.qt.io/browse/QTBUG-43217
        if pymol.IS_MACOS:
            self.menudict['Edit'].setTitle('Edit_')
            QtCore.QTimer.singleShot(
                10, lambda: self.menudict['Edit'].setTitle('Edit'))

        # recent files menu
        if self.open_recent_menu:

            @self.open_recent_menu.aboutToShow.connect
            def _():
                self.open_recent_menu.clear()
                for fname in self.recent_filenames:
                    self.open_recent_menu.addAction(
                        fname if len(fname) < 128 else '...' + fname[-120:],
                        lambda fname=fname: self.load_dialog(fname))

        # some experimental window control
        menu = self.menudict['Display'].addSeparator()
        menu = self.menudict['Display'].addMenu('External GUI')
        menu.addAction('Toggle floating', self.toggle_ext_window_dockable,
                       QtGui.QKeySequence('Ctrl+E'))
        ext_vis_action = self.ext_window.toggleViewAction()
        ext_vis_action.setText('Visible')
        menu.addAction(ext_vis_action)

        # extra key mappings (MacPyMOL compatible)
        QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+O'),
                            self).activated.connect(self.file_open)
        QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+S'),
                            self).activated.connect(self.session_save)

        # feedback
        self.feedback_timer = QtCore.QTimer()
        self.feedback_timer.setSingleShot(True)
        self.feedback_timer.timeout.connect(self.update_feedback)
        self.feedback_timer.start(100)

        # legacy plugin system
        self.menudict['Plugin'].addAction('Initialize Plugin System',
                                          self.initializePlugins)

        # focus in command line
        if options.external_gui:
            self.lineedit.setFocus()
        else:
            self.pymolwidget.setFocus()

        # Apply PyMOL stylesheet
        try:
            with open(
                    cmd.exp_path('$PYMOL_DATA/pmg_qt/styles/pymol.sty')) as f:
                style = f.read()
        except IOError:
            print('Could not read PyMOL stylesheet.')
            print('DEBUG: PYMOL_DATA=' + repr(os.getenv('PYMOL_DATA')))
            style = ""

        if style:
            self.setStyleSheet(style)