文本窗口小部件中的Tkinter滚动条(Scrollbar in Tkinter inside Text widget)
我在Tkinter的Text小部件里面的Scrollbar中设置了问题。 我知道,最好使用网格来定位窗口小部件,但我想将窗口小部件设置为绝对位置(x,y - GUI图片上的红点),并指定高度和宽度。
我的代码:
from Tkinter import * from ttk import * class NotebookDemo(Frame): def __init__(self): Frame.__init__(self) self.pack(expand=1, fill=BOTH) self.master.title('Sample') self.master.geometry("650x550+100+50") self._initUI() def _initUI(self): self._createPanel() def _createPanel(self): # create frame inside top level frame panel = Frame(self) panel.pack(side=TOP, fill=BOTH, expand=1) # create the notebook nb = Notebook(panel) nb.pack(fill=BOTH, expand=1, padx=2, pady=3) self._FirstTab(nb) def _FirstTab(self, nb): # frame to hold content frame = Frame(nb) #textbox txtOutput = Text(frame, wrap = NONE, height = 17, width = 70) txtOutput.place(x=10, y=75) #button btnStart = Button(frame, text = 'Start', underline=0) btnStart.place(x=220, y=380) #scrollbar #vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview) #txtOutput['yscroll'] = vscroll.set #vscroll.pack(side=RIGHT, fill=Y) #txtOutput.pack(fill=BOTH, expand=Y) #add to notebook (underline = index for short-cut character) nb.add(frame, text='TAB 1', underline=0, padding=2) if __name__ == '__main__': app = NotebookDemo() app.mainloop()
如果我取消注释这部分代码(设置Scrollbar):
vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview) txtOutput['yscroll'] = vscroll.set vscroll.pack(side=RIGHT, fill=Y)
我的滚动条位于所有窗口内,不在文本框内:
但是我当然希望在文本框小部件(黑色边框)内部使用滚动条。 如果我使用pack函数到文本框:
txtOutput.pack(fill=BOTH, expand=Y)
文本小部件填写整个窗口...:
我真的不知道如何解决这个问题。 任何帮助将不胜感激。 谢谢!
编辑:
当然我也可以使用滚动条的方法,但我不能改变它们的长度,因为它没有属性长度。
vscroll.place(x=573, y=75)
I have problem with set in Scrollbar inside Text widget in Tkinter. I know, that it's preferable to use grid to locate widgets but I want to set my widget in absolute location (x,y - red dot on GUI picture) with specified height and width.
My code:
from Tkinter import * from ttk import * class NotebookDemo(Frame): def __init__(self): Frame.__init__(self) self.pack(expand=1, fill=BOTH) self.master.title('Sample') self.master.geometry("650x550+100+50") self._initUI() def _initUI(self): self._createPanel() def _createPanel(self): # create frame inside top level frame panel = Frame(self) panel.pack(side=TOP, fill=BOTH, expand=1) # create the notebook nb = Notebook(panel) nb.pack(fill=BOTH, expand=1, padx=2, pady=3) self._FirstTab(nb) def _FirstTab(self, nb): # frame to hold content frame = Frame(nb) #textbox txtOutput = Text(frame, wrap = NONE, height = 17, width = 70) txtOutput.place(x=10, y=75) #button btnStart = Button(frame, text = 'Start', underline=0) btnStart.place(x=220, y=380) #scrollbar #vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview) #txtOutput['yscroll'] = vscroll.set #vscroll.pack(side=RIGHT, fill=Y) #txtOutput.pack(fill=BOTH, expand=Y) #add to notebook (underline = index for short-cut character) nb.add(frame, text='TAB 1', underline=0, padding=2) if __name__ == '__main__': app = NotebookDemo() app.mainloop()
If I uncomment this part of code (set Scrollbar):
vscroll = Scrollbar(frame, orient=VERTICAL, command=txtOutput.yview) txtOutput['yscroll'] = vscroll.set vscroll.pack(side=RIGHT, fill=Y)
My Scrollbar is located inside all window, not inside Text box:
But of course I want to have the Scrollbar inside the Text box widget (black border). If I use pack function to textbox:
txtOutput.pack(fill=BOTH, expand=Y)
text widget fill in the whole window...:
I really don't know how fix this problem. Any help will be appreciated. Thank you!
EDIT:
Of course I can use place method with Scrollbar too, but I can't change length of them, because it hasn't attribute length.
vscroll.place(x=573, y=75)
原文:https://stackoverflow.com/questions/41976546
最满意答案
Bluebird具有允许“节流”的额外好处。
var Promise = require('bluebird'); var request = require('request-promise'); // since we'll be using promises Promise.map(arrayOfUrls, function(url){ return request(url) .then(function(data){ return JSON.parse(data); // format / manipulate your data }) }).then(function(results){ // results will be an array of JSON objects })
这将以节点可以处理它们的速度快速调度所有请求。 如果它是您自己的服务器,那可能没问题但是为了防止“Too Many Requests error”,请将以下内容添加到
map
调用中Promise.map(arrayOfUrls, function, { concurrency: 4 }); // no more than 4 requests will run at once. Thanks Bluebird
Bluebird has the added benefit of allowing "throttling".
var Promise = require('bluebird'); var request = require('request-promise'); // since we'll be using promises Promise.map(arrayOfUrls, function(url){ return request(url) .then(function(data){ return JSON.parse(data); // format / manipulate your data }) }).then(function(results){ // results will be an array of JSON objects })
This will dispatch all the requests as fast as node can handle them. If it's your own server, that could be ok but to prevent a "Too Many Requests error", add the following to your
map
callPromise.map(arrayOfUrls, function, { concurrency: 4 }); // no more than 4 requests will run at once. Thanks Bluebird
相关问答
更多-
当您制作一个新的AJAX电话时,您应该始终放弃以前的AJAX电话。 它将帮助您的服务器并为用户提供理想的结果。 var xhr; function makeRequest() { if (xhr) xhr.abort(); xhr = $.ajax(...); } You should always abort previous AJAX call, when you are making a new one. It will help your server and ...
-
我不知道CoffeeScript,所以这是一个纯粹的jQuery解决方案: 如果不进行同步调用,则无法从get_total 返回值。 一旦所有请求都完成,你可以做的就是调用回调函数。 这个例子使用了jQuery的Deferred对象[docs] : function get_total(trend, duration, callback) { var deferreds = [], total = 0; for(var i = 0, l = trend.search_terms.lengt ...
-
Redis多个请求(Redis multiple requests)[2022-03-28]
您可以轻松地重构代码,通过使用管道(redis-rb支持)将15个请求合并为一个。 您可以使用第一个请求从排序集中获取ID,然后根据这些结果使用它们获取所需的许多键(使用管道) 使用这种方法,您应该总共有2个请求而不是16个,并且保持代码非常简单。 作为替代方案,您可以使用lua脚本并在一个请求中获取所有内容。 You can easily refactor your code to collapse the 15 requests in one by using pipelines (which redi ... -
您可以依靠Promises在您的解决方案之前执行它们。 如果你习惯了jQuery,你也可以使用jQuery Promise。 随着Promise.all你将强制每一个请求都已完成,然后继续执行代码 Promise.all([ fetch("http://localhost:3000/items/get"), fetch("http://localhost:3000/contactlist/get"), fetch("http://localhost:3000/itemgroup/get") ]) ...
-
根据Scrapy邮件列表中的建议 , Autothrottle中间件遵循一个特殊的请求元变量,称为download_slot - 这允许对请求进行编程分组/限制。 在我的自定义代理中间件中: self.proxies = get_proxies() #list of proxies proxy_address = random.choice(self.proxies) request.meta['proxy'] = proxy_address request.meta['download_slot'] = ...
-
没有一些代码可以看,我们的答案必须相当一般。 但在我看来,你需要彻底改变你的启动流程。 如果按顺序发生HTTP请求很重要,则需要按顺序调用它们 - 嵌套在彼此的完成委托方法中。 您可以使用ASIHTTPRequest的.userInfo字段来识别您正在触发的不同类型的请求。 你的didFinishLaunching方法应该足够让你的第一个请求开始(也许会带来一个“加载”视图),然后其他的应用程序启动工作需要在各种requestDidFinish方法中完成。 如果您也掌控网站的一部分,您可能会看到您可以将多少 ...
-
基本上,您需要为每个请求设置可访问性标签 for task 1 [dataTask setAccessibilityLabel:@"label1"]; for task 2 [dataTask setAccessibilityLabel:@"label2"]; 然后在委托方法中检查辅助功能标签 if([dataTask.accessibilityLabel isEqual: @"label1"]) { // handle data ...
-
多个each和ajax请求(Multiple each and ajax requests)[2023-08-18]
问题在于, when对延迟对象进行操作时,sub不会返回任何内容,因此立即触发。 所以你需要做的是收集ajax调用返回的所有延迟对象并返回它们: var order = []; function sub(selector){ var deferredList = [] selector.each(function(){ var out = { "some":"random", "stuff":"here" }; ... -
获取多个请求(Get Multiple Requests)[2023-01-26]
Bluebird具有允许“节流”的额外好处。 var Promise = require('bluebird'); var request = require('request-promise'); // since we'll be using promises Promise.map(arrayOfUrls, function(url){ return request(url) .then(function(data){ return JSON.par ... -
Siesta处理多个请求(Siesta handling multiple requests)[2021-06-18]
Siesta不控制请求排队的方式或同时运行的请求数。 你有两个选择: 在应用程序端控制它,或 在网络层控制它。 我先调查选项2。 它为您提供了较少的细粒度控制,但它以更低的成本为您提供更强大的选项,并且不容易出错。 如果您使用URLSession作为网络层(这是Siesta的默认设置),那么请调查HTTPMaximumConnectionsPerHost属性是否满足您的需要。 (以下是将自定义配置传递给Siesta的一些示例 。) 如果这对您不起作用,#1的简单版本是使用完成处理程序来链接请求: func ...