Python tkinter canvas在启动期间获得可见区域

时间:2017-11-03 09:51:59

标签: python canvas tkinter

我无法在它的初始化期间获得画布画布给我可见区域,我需要在此期间获得可见区域的原因是我需要坐标来确定立即向用户显示的内容创作之后。

按下按钮后,画布会在__init__之后正确打印它的区域,但在.grid() __init__try: import tkinter as tk except: import Tkinter as tk class app(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.grid_columnconfigure(0,weight=1) self.grid_rowconfigure(1,weight=1) self.vis_area_btn = tk.Button(self,text="Print Visible Area", command=self.prnt_vis_area) self.canvas = tk.Canvas(self,bg="white",highlightthickness=0) self.vis_area_btn.grid(row=0,column=0,sticky="nswe") self.canvas.grid(row=1,column=0,sticky="nswe") self.prnt_vis_area() def prnt_vis_area(self,event=None): #self.canvas.configure(scrollregion=(0,0,1,1)) x1 = self.canvas.canvasx(0) y1 = self.canvas.canvasy(0) x2 = self.canvas.canvasx(self.canvas.winfo_width()) y2 = self.canvas.canvasy(self.canvas.winfo_height()) print (x1,y1,x2,y2) root = app() root.mainloop() 之后调用该功能时不会

var started = false;
var canvas, context;
var stampId = '';
var lastColor = 'black';
var lastStampId = '';
var enableDraw = false;

function init() {
    canvas = $('#imageView').get(0);
    context = canvas.getContext('2d');

    // Auto-adjust canvas size to fit window.
    canvas.width = window.innerWidth - 75;
    canvas.height = window.innerHeight - 75;

    //$('#container').get(0).addEventListener('mousemove', onMouseMove, false);
    canvas.addEventListener('mousemove', onMouseMove, false);
    canvas.addEventListener('click', onClick, false);
    canvas.addEventListener('mousedown', function (e) {
        enableDraw = true;
    }, false);
    canvas.addEventListener('mouseup', function (e) {
        enableDraw = false;
        started = false;
    }, false);

    // Add events for toolbar buttons.
    $('#red').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#pink').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#fuchsia').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#orange').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#yellow').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#lime').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#green').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#blue').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#purple').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#black').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#white').get(0).addEventListener('click', function (e) {
        onColorClick(e.target.id);
    }, false);
    $('#cat').get(0).addEventListener('click', function (e) {
        onStamp(e.target.id);
    }, false);
    $('#dragonfly').get(0).addEventListener('click', function (e) {
        onStamp(e.target.id);
    }, false);
    $('#ladybug').get(0).addEventListener('click', function (e) {
        onStamp(e.target.id);
    }, false);
    $('#heart').get(0).addEventListener('click', function (e) {
        onStamp(e.target.id);
    }, false);
    $('#dog').get(0).addEventListener('click', function (e) {
        onStamp(e.target.id);
    }, false);
    $('#fill').get(0).addEventListener('click', function (e) {
        onFill();
    }, false);
    $('#save').get(0).addEventListener('click', function (e) {
        onSave();
    }, false);
}

function onMouseMove(ev) {
    var x, y;

    // Get the mouse position.
    if (ev.layerX >= 0) {
        // Firefox
        x = ev.layerX - 0;
        y = ev.layerY - 0;
    }
    else if (ev.offsetX >= 0) {
        // Opera
        x = ev.offsetX - 0;
        y = ev.offsetY - 0;
    }

    if (enableDraw && stampId.length === 0) {
        if (!started) {
            started = true;
            context.beginPath();
            context.moveTo(x, y);
        }
        else {
            context.lineTo(x, y);
            context.stroke();
        }
    }

    $('#stats').text('x ' + x + ', ' + 'y ' + y);
    $('#size').text('width ' + canvas.width + ', ' + 'height' + canvas.height);
}

function onClick(e) {
    if (stampId.length > 0) {
        context.drawImage($(stampId).get(0), e.pageX - 90, e.pageY - 60, 80, 80);
    }
}

function onColorClick(color) {
    // Start a new path to begin drawing in a new color.
    context.closePath();
    context.beginPath();

    // Select the new color.
    context.strokeStyle = color;

    // Highlight selected color.
    var borderColor = 'white';
    if (color === 'white' || color === 'yellow') {
        borderColor = 'black';
    }

    $('#' + lastColor).css("border", "0px dashed white");
    $('#' + color).css("border", "1px dashed " + borderColor);

    // Store color so we can un-highlight it next time around.
    lastColor = color;

    // Turn off any stamp selection, since we're painting again.
    $(stampId).css("border", "0px dashed white");
    stampId = '';
}

function onFill() {
    // Start a new path to begin drawing in a new color.
    context.closePath();
    context.beginPath();

    context.fillStyle = context.strokeStyle;
    context.fillRect(0, 0, canvas.width, canvas.height);
}

function onStamp(id) {
    // Update the stamp image.
    stampId = '#' + id;

    if (lastStampId === stampId) {
        // User clicked the selected stamp again, so deselect it.
        stampId = '';
    }

    $(lastStampId).css("border", "0px dashed white");
    $(stampId).css("border", "1px dashed black");

    $('#' + lastColor).css("border", "0px dashed white");

    // Store stamp so we can un-highlight it next time around.
    lastStampId = stampId;
}

function onSave() {
    var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream.png");
    window.location.href=image;
}

1 个答案:

答案 0 :(得分:3)

这是一个非常简单的修复方法。

tkinter有一个名为.update()的函数,解释为here

  

处理所有待处理事件,调用事件回调,完成任何挂起的几何管理,根据需要重绘小部件,并调用所有挂起的空闲任务。应谨慎使用此方法,因为如果从错误的位置(例如,从事件回调中调用,或者从可以以任何方式从事件回调中调用的函数等)调用它,可能会导致非常讨厌的竞争条件)。如有疑问,请改用update_idletasks

简而言之,您需要知道的是,在致电self.canvas.update()之前添加self.prnt_vis_area()可以解决您的问题。

def __init__(self):
    tk.Tk.__init__(self)
    self.grid_columnconfigure(0,weight=1)
    self.grid_rowconfigure(1,weight=1)
    self.vis_area_btn = tk.Button(self,text="Print Visible Area",
                                  command=self.prnt_vis_area)
    self.canvas = tk.Canvas(self,bg="white",highlightthickness=0)
    self.vis_area_btn.grid(row=0,column=0,sticky="nswe")
    self.canvas.grid(row=1,column=0,sticky="nswe")
    self.canvas.update() #here
    self.prnt_vis_area()