- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个 Text
小部件,它包含一个包含 \n
字符(多行)的自定义字符串。
小部件放置在一个垂直的 panedwindow
中,我想调整 panedwindow
的窗框以在 Text
中显示整个字符串小部件。
该字符串本质上是动态的(这意味着,它正在通过我的应用程序中的其他方法进行更新)。
由于 Text
小部件配置有 wrap='word'
,我如何计算以像素为单位的字符串高度以相应地调整窗扇?
我尝试在之后使用 text.dlineInfo('end -1c')[1] + text.dlineinfo('end -1c')[3]
(用于行的 y 坐标 + 高度)字符串已加载到小部件。问题是,如果最后一行不可见,则 dlineinfo 返回 none
。
我还尝试使用 Font.measure
例程,但这不包括 Text
小部件的换行方面。
这是一个最小的、完整的和可验证的例子:
import tkinter
from tkinter import scrolledtext
class GUI():
def __init__(self, master):
self.master = master
self.body_frame = tkinter.PanedWindow(self.master, orient='vertical', sashwidth=4)
self.body_frame.pack(expand=1, fill='both')
self.canvas_frame = tkinter.Frame(self.body_frame)
self.description_frame = tkinter.Frame(self.body_frame)
self.body_frame.add(self.canvas_frame, sticky='nsew')
self.body_frame.add(self.description_frame, sticky='nsew')
tkinter.Button(self.canvas_frame, text='Update Text', command = lambda : self.update_text("""
A very long string with new lines
A very long string with new lines
A very long string with new lines
A very long string with new lines
A very long string with new lines
A very long string with new lines
""")).pack(fill='x')
self.field_description = scrolledtext.ScrolledText(self.description_frame, width=20, wrap='word')
self.field_description.pack(expand=1, fill='both')
self.master.update()
self.body_frame.sash_place(0,0,self.body_frame.winfo_height() - 50) # force sash to be lower
def update_text(self, description):
self.field_description.delete('1.0', 'end')
self.field_description.insert('1.0', description)
height = self.body_frame.winfo_height()
lastline_index = self.field_description.index('end - 1c')
text_height = self.field_description.dlineinfo(lastline_index)[1] + \
self.field_description.dlineinfo(lastline_index)[3]
self.body_frame.sash_place(0, 0, height - text_height)
root = tkinter.Tk()
my_gui = GUI(root)
root.mainloop()
最佳答案
我不知道有任何内置方法可以返回 tkinter Text
中的总行数(包括换行) > 小部件。
但是,您可以通过比较文本小部件中完整字符串的长度与文本小部件的确切宽度(减去填充)来手动计算此数字。下面的 LineCounter
类就是这样做的:
# python 2.x
# from tkFont import Font
# python 3.x
from tkinter.font import Font
class LineCounter():
def __init__(self):
"""" This class can count the total number of lines (including wrapped
lines) in a tkinter Text() widget """
def count_total_nb_lines(self, textWidget):
# Get Text widget content and split it by unbroken lines
textLines = textWidget.get("1.0", "end-1c").split("\n")
# Get Text widget wrapping style
wrap = text.cget("wrap")
if wrap == "none":
return len(textLines)
else:
# Get Text widget font
font = Font(root, font=textWidget.cget("font"))
totalLines_count = 0
maxLineWidth_px = textWidget.winfo_width() - 2*text.cget("padx") - 1
for line in textLines:
totalLines_count += self.count_nb_wrapped_lines_in_string(line,
maxLineWidth_px, font, wrap)
return totalLines_count
def count_nb_wrapped_lines_in_string(self, string, maxLineWidth_px, font, wrap):
wrappedLines_count = 1
thereAreCharsLeftForWrapping = font.measure(string) >= maxLineWidth_px
while thereAreCharsLeftForWrapping:
wrappedLines_count += 1
if wrap == "char":
string = self.remove_wrapped_chars_from_string(string,
maxLineWidth_px, font)
else:
string = self.remove_wrapped_words_from_string(string,
maxLineWidth_px, font)
thereAreCharsLeftForWrapping = font.measure(string) >= maxLineWidth_px
return wrappedLines_count
def remove_wrapped_chars_from_string(self, string, maxLineWidth_px, font):
avgCharWidth_px = font.measure(string)/float(len(string))
nCharsToWrap = int(0.9*maxLineWidth_px/float(avgCharWidth_px))
wrapLine_isFull = font.measure(string[:nCharsToWrap]) >= maxLineWidth_px
while not wrapLine_isFull:
nCharsToWrap += 1
wrapLine_isFull = font.measure(string[:nCharsToWrap]) >= maxLineWidth_px
return string[nCharsToWrap-1:]
def remove_wrapped_words_from_string(self, string, maxLineWidth_px, font):
words = string.split(" ")
nWordsToWrap = 0
wrapLine_isFull = font.measure(" ".join(words[:nWordsToWrap])) >= maxLineWidth_px
while not wrapLine_isFull:
nWordsToWrap += 1
wrapLine_isFull = font.measure(" ".join(words[:nWordsToWrap])) >= maxLineWidth_px
if nWordsToWrap == 1:
# If there is only 1 word to wrap, this word is longer than the Text
# widget width. Therefore, wrapping switches to character mode
return self.remove_wrapped_chars_from_string(string, maxLineWidth_px, font)
else:
return " ".join(words[nWordsToWrap-1:])
使用示例:
import tkinter as tk
root = tk.Tk()
text = tk.Text(root, wrap='word')
text.insert("1.0", "The total number of lines in this Text widget is " +
"determined accurately, even when the text is wrapped...")
lineCounter = LineCounter()
label = tk.Label(root, text="0 lines", foreground="red")
def show_nb_of_lines(evt):
nbLines = lineCounter.count_total_nb_lines(text)
if nbLines < 2:
label.config(text="{} line".format(nbLines))
else:
label.config(text="{} lines".format(nbLines))
label.pack(side="bottom")
text.pack(side="bottom", fill="both", expand=True)
text.bind("<Configure>", show_nb_of_lines)
text.bind("<KeyRelease>", show_nb_of_lines)
root.mainloop()
在您的特定情况下,ScrolledText
中环绕文本的高度可以在 update_text()
中确定,如下所示:
from tkinter.font import Font
lineCounter = LineCounter()
...
class GUI():
...
def update_text(self, description):
...
nbLines = lineCounter.count_total_nb_lines(self.field_description)
font = Font(font=self.field_description.cget("font"))
lineHeight = font.metrics("linespace")
text_height = nbLines * lineHeight
...
关于python - Tkinter.text - 如何计算动态字符串的高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45470163/
我目前正在创建一个正则表达式来拆分所有匹配以下格式的字符串:&[text(text - text text) !text]。这里的文本实际上可以是任何字符。并且间距很重要。文本将如图所示列出。 我已经
这个问题在这里已经有了答案: Remove duplicate commas and extra commas at start/end with RegExp in Javascript, and
我有以下代码。 from xml.dom.minidom import Document doc = Document() root = doc.createElement('root') doc.a
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Find text string in jQuery and make it bold 如何使用 jQuer
我使用 libmagic 在我的元素的 Web 界面中获取文件的 MIME 类型。我在 css 和 js 文件上得到文本/纯 mime 类型。 例如 chromium 显示以下警告: Resource
起初我必须阅读很多教程,但我仍然不知道我做错了什么...... 我想内联使用 4 个 div。在我想放置的那些 div 中:文本、图像、文本、文本。我希望中间文本自动设置为最大宽度。 我写了一个简单的
我想替换所有出现的 [b: "text"]至text使用 JavaScript 和 RegEx。目前我知道如何替换 [b: ""]至使用'/\[b: ""\]/g'但我不知道如果 " 之间有文本该怎么
这可能是一个幼稚的问题,但我想知道是否有比使用 text() 更好的方法将文本添加到绘图中。注意,我也在使用 layout()以及。具体来说,我有一个情节的一部分,我想在其中添加一些带有标题的文本,然
我必须反复从 latex 源粘贴代码,因此每次都必须做很多查找和替换操作('“a'=>'ä','” o'=>'ö',...) 。 有没有一种方法可以存储这些搜索和替换规则,例如,我可以通过一次按键执行
当我在Sublime Text 3代码屏幕中编写代码时,它连续地向右滑动,如图所示。我该怎么办? 请注意第10行。 最佳答案 如果您只想为当前 View (正在编辑的当前文件)激活自动换行,只需vie
是否有可能更改 sublime text 中的默认字体目录?我只想使用可移植 sublime 文本存储在我的 pendrive 上的字体,这样我就不必在我使用可移植 sublime 文本的每台机器上安
我是 Android 开发的新手,我有一个愚蠢的问题。如何将“文本字段”框放在一行中的文本旁边。 例子: Please Enter the number: [ ] 关于 "t
我想自动将“我的文本”更改为“我的文本”,因为这是用德语写的正确方式。引号可以在文本中的任何位置。 有没有一种简单的方法可以实现这一点? 解决方案应该检查第一个字符,最后一个字符,比如“this”,或
我想知道是否有特殊的语法来绑定(bind)与现有文本连接的文本。 像这样。 显然,这行不通。 什么是最佳实践? 使用 SL4。 最佳答案 使用StringFormat在 Binding 上。 WPF
我认为它应该打印“真实文本”,因为它相当于 true console.log('true text' || true ? 'text' : 'text1'); 但是,输出是“文本”;抱歉,如果是愚蠢的
有没有办法通过 css 打破文本,以便中间有一个“空白”?目前我正在通过手工打破文本来解决这个问题 -但这是愚蠢的。我知道有一个函数可以让文本在另一个 div 中结束和开始,但 IE 不支持它。 文本
我想为我的Tcl/Tk工具实现一个效果:在text控件中,根据具体情况,希望高亮一些线条的背景色,其他线条正常透明.有可能吗? 我尝试了一些选项,例如:-highlightbackground 、-i
我正在尝试解析原始维基百科文章内容,例如the article on Sweden ,使用re.sub()。但是,我在尝试替换 {{some text}} block 时遇到了问题,因为它们可以包含更
我试图先删除 ComboBox 中的所有内容。然后在其前面添加文本,但保留了一些旧文本。有没有办法重置或清除 ComboBox?或者我怎样才能最好地实现这一目标? public void GetBad
我知道我们应该创建 Example对象并将其传递给 nlp.update() 方法。根据 docs 中的示例, 我们有 for raw_text, entity_offsets in train_da
我是一名优秀的程序员,十分优秀!