嵌入matplotlib会混淆GTK3 dpi

时间:2017-05-15 13:16:10

标签: python-3.x matplotlib gtk3 dpi pygobject

我有一个应用程序,它使用GTK3为python 3显示一个GUI。它有一个由matplotlib呈现的图。当绘图包含在代码中时,UI会放大(参见图片)。这发生在具有视网膜显示的Mac上。在Ubuntu上它完美无缺。以下是绘制GUI的代码:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

from matplotlib.figure import Figure
import matplotlib.cm as cm
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas

from threading import Thread
import os

from instruction import *
from instructionwriter import *

class UI:
    def __init__(self):
        self.instructions = None

        self.builder = Gtk.Builder()
        self.builder.add_from_file(os.path.dirname(os.path.realpath(__file__)) + os.path.sep + "UI.glade")
        self.builder.connect_signals(self)

        scale = self.builder.get_object("scale")
        scale.set_label("Välj skalfaktor")
        scale.set_relief(Gtk.ReliefStyle.NORMAL)

        # This part has to be commented out to make the GUI display correctly but is needed for the application.
        #self.fig = Figure()
        #self.fig.suptitle("Förhandsvisning")
        #self.ax = self.fig.add_subplot(1, 1, 1)

        #self.canvas = FigureCanvas(self.fig)
        #self.builder.get_object("scrolledwindow1").add_with_viewport(self.canvas)

        #self._preview()

        self.buttons = [
            self.builder.get_object("filechooser"),
            self.builder.get_object("centerbutton"),
            self.builder.get_object("scale"),
            self.builder.get_object("autobutton"),
            self.builder.get_object("preview"),
            self.builder.get_object("save")
        ]
        self.lastScale = 0.5

        statusBar = self.builder.get_object("statusBar")
        self.context_id = statusBar.get_context_id("id")

    def show(self):
        self.builder.get_object("window1").show_all()

    def on_exit(self, *args):
        Gtk.main_quit()

    def on_file_select(self, *args):
        filename = self.builder.get_object("filechooser").get_filename()
        self.builder.get_object("snurrare").start()
        self._disable_ui()
        Thread(target=self._load, args=(filename,)).start()

    def on_preview(self, *args):
        self._preview()
        self._display_time()

    def on_center(self, *args):
        self.instructions.center()

    def on_fit(self, *args):
        self.instructions.fit()

    def on_save(self, *args):
        dialog = Gtk.FileChooserDialog("Välj mapp", self.builder.get_object("window1"),
            Gtk.FileChooserAction.SELECT_FOLDER,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
             "Välj", Gtk.ResponseType.OK))
        dialog.set_default_size(800, 400)

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            self.builder.get_object("snurrare").start()
            self._disable_ui()
            Thread(target=self._save, args=(dialog.get_filename(),)).start()
        dialog.destroy()

    def _load(self, filename):
        self.lastScale = 0.5
        self.builder.get_object("scale").set_value(0.5)

        ext = os.path.splitext(filename)[1]
        if ext == ".svg":
            self.instructions = InstructionList.from_svg(filename)
        elif ext == ".py":
            self.instructions = InstructionList.from_code(filename)

        self.builder.get_object("snurrare").stop()
        self._display_time()
        self._enable_ui()

    def _save(self, folder):
        writer = InstructionWriter(self.instructions, 0)
        writer.write(folder)

        self.builder.get_object("snurrare").stop()
        self._enable_ui()

    def _disable_ui(self):
        for button in self.buttons:
            button.set_sensitive(False)

    def _enable_ui(self):
        for button in self.buttons:
            button.set_sensitive(True)

    def _preview(self):
        if not self.instructions is None:
            if self.builder.get_object("scale").get_value() != self.lastScale:
                self.lastScale = self.builder.get_object("scale").get_value()
                self.instructions.scale(2*self.lastScale)

            self.ax.clear()

            x = []
            y = []
            for inst in self.instructions.instructions:
                if inst.type == Instruction.MOVE:
                    self.ax.plot(x, y, 'b')
                    x = [inst.dest.real]
                    y = [inst.dest.imag]
                elif inst.type == Instruction.LINE:
                    x.append(inst.dest.real)
                    y.append(inst.dest.imag)

            self.ax.plot(x, y, 'b')
        self.ax.plot([-XLIM, XLIM, XLIM, -XLIM, -XLIM], [-YLIM, -YLIM, YLIM, YLIM, -YLIM], 'r')
        self.ax.plot([-585, 585, 585, -585, -585], [-413.5, -413.5, 413.5, 413.5, -413.5], 'g:')
        self.ax.axis("equal")
        self.fig.canvas.draw()

    def _display_time(self):
        t = self.instructions.time()
        self.builder.get_object("statusBar").push(self.context_id, "Uppskattad tid: %dmin %ds" % (t//60, t%60))

ui = UI()
ui.show()
Gtk.main()

包含情节时的GUI

GUI when plot is included

排除情节时的

GUI

GUI when plot is excluded

0 个答案:

没有答案