英文:
How to display text that can be copied on a fyne GUI?
问题
在我的fyne GUI中,我想要显示可以被用户复制的文本。到目前为止,我正在使用一个(多行)widget.Entry,请参考下面的示例。虽然这样可以工作,但似乎不太合适,因为“entry”暗示着用户输入,而这里并非如此。
如果我使用widget.Label或canvas.Text,字符无法被复制。那么在这种情况下,最好的方法是什么?
示例:
package main
import (
	"time"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/data/binding"
	"fyne.io/fyne/v2/widget"
)
func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("demo")
	txtBound := binding.NewString()
	txtWid := widget.NewEntryWithData(txtBound)
	txtWid.MultiLine = true
    // 我们可以禁用Entry字段,这样用户就无法修改文本:
    txtWid.Disabled()
	go func() {
		for {
			txtBound.Set(time.Now().Format("2006-01-02\n15:04:05\nMST -0700"))
			time.Sleep(time.Second)
		}
	}()
	content := container.NewBorder(nil, nil, nil, nil, txtWid)
	myWindow.SetContent(content)
	myWindow.Resize(fyne.NewSize(500, 300))
	myWindow.ShowAndRun()
}
可以通过鼠标/右键上下文菜单或Ctrl+C选择并复制Entry字段中的文本。在Windows 10上,效果如下图所示:

英文:
On my fyne GUI, I want to display text that can be copied by the user. So far, I'm using a (multi-line) widget.Entry, see example below. Although that works, it seems inappropriate since "entry" implies user-input - which is not the case here.
If I use a widget.Label or canvas.Text, the characters can't be copied. So what's the best approach here?
Example:
package main
import (
	"time"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/data/binding"
	"fyne.io/fyne/v2/widget"
)
func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("demo")
	txtBound := binding.NewString()
	txtWid := widget.NewEntryWithData(txtBound)
	txtWid.MultiLine = true
    // we can disable the Entry field so the user can't modify the text:
    txtWid.Disabled()
	go func() {
		for {
			txtBound.Set(time.Now().Format("2006-01-02\n15:04:05\nMST -0700"))
			time.Sleep(time.Second)
		}
	}()
	content := container.NewBorder(nil, nil, nil, nil, txtWid)
	myWindow.SetContent(content)
	myWindow.Resize(fyne.NewSize(500, 300))
	myWindow.ShowAndRun()
}
The text in the Entry field can be selected and then copied using either mouse/right-click context menu or ctrl-c. On Windows 10, that would look like

答案1
得分: 3
为了补充andy.xyz的回答,这里有一个示例,展示了如何使用按钮将特定内容复制到剪贴板。Fyne窗口有一个名为Clipboard的类型,提供了必要的接口,例如:
import (
	"time"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/data/binding"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)
func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("demo")
	txtBound := binding.NewString()
	txtWid := widget.NewLabelWithData(txtBound)
	bottomBox := container.NewHBox(
		layout.NewSpacer(),
		widget.NewButtonWithIcon("copy content", theme.ContentCopyIcon(), func() {
			if content, err := txtBound.Get(); err == nil {
				myWindow.Clipboard().SetContent(content)
			}
		}),
	)
	content := container.NewBorder(nil, bottomBox, nil, nil, txtWid)
	go func() { // make changing content...
		for {
			txtBound.Set(time.Now().Format("2006-01-02\n15:04:05\nMST -0700"))
			time.Sleep(time.Second)
		}
	}()
	myWindow.SetContent(content)
	myWindow.Resize(fyne.NewSize(500, 300))
	myWindow.ShowAndRun()
}
英文:
To complement andy.xyz's answer, here's an example of how a button can be used to copy a certain content to the clipboard. Fyne windows have a Clipboard type that provides the necessary interface, e.g.
import (
	"time"
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/data/binding"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)
func main() {
	myApp := app.New()
	myWindow := myApp.NewWindow("demo")
	txtBound := binding.NewString()
	txtWid := widget.NewLabelWithData(txtBound)
	bottomBox := container.NewHBox(
		layout.NewSpacer(),
		widget.NewButtonWithIcon("copy content", theme.ContentCopyIcon(), func() {
			if content, err := txtBound.Get(); err == nil {
				myWindow.Clipboard().SetContent(content)
			}
		}),
	)
	content := container.NewBorder(nil, bottomBox, nil, nil, txtWid)
	go func() { // make changing content...
		for {
			txtBound.Set(time.Now().Format("2006-01-02\n15:04:05\nMST -0700"))
			time.Sleep(time.Second)
		}
	}()
	myWindow.SetContent(content)
	myWindow.Resize(fyne.NewSize(500, 300))
	myWindow.ShowAndRun()
}
答案2
得分: 2
标签仅用于显示,不提供用户交互 - 这是网络应用程序让我们感到困惑的一点 ![]()
在 Fyne 应用中,我们的目标是提示所有用户交互,按钮和链接是可交互的,文本则不是。
有两种可能的方法:
1)在标签旁边放置一个“复制”按钮,这在许多应用程序中已成为常见做法(例如密码管理器或 YouTube)。
2)使用禁用的输入框(Entry),以便可以与文本进行交互,但不能编辑。
英文:
Labels are for display only, they afford no user interaction - this is something that web based apps have confused us about :).
In Fyne apps we aim to have all user interaction hinted at, buttons and links are interactive, text is not.
There are two possible approaches:
- put a “copy” button next to your label as has become common practice in many apps (for example password managers or YouTube)
 - use a disabled Entry so the text can be interacted with but not edited.
 
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论