go 使用fyne实现桌面程序的计算器例子

【Go语言】Fyne GUI 库使用指南 (面向有经验开发者) Fyne 允许开发者创建自定义组件,以满足特定需求。自定义布局需要实现接口,该接口定义了如何排列和调整容器中的对象大小。import (// 自定义布局:将所有元素堆叠在一起,但每个元素有一个偏移量// MinSize 计算所有子元素所需的最小尺寸// Layout 排列子元素// 创建三个按钮btn1 := widget.NewButton("按钮 1", nil)btn2 := widget.NewButton("按钮 2", nil) 阅读详情

使用Fyne工具包构建跨平台应用是非常简单的,在此之前我们需要做一些准备功能做,比如安装一些gcc基础图形依赖库,还有go语言本身的运行开发环境都是必要的。

在此之前我们希望你是go语言的已入门用户,掌握go的协程,管道,以及大多数语法,这样会让你学习起来更轻松

下面是实现的代码,有一部分还没有实现,如果需要可以继续研究.

package main

import (
	"image/color"
	"math"
	"strconv"
	"strings"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"fyne.io/fyne/v2/driver/desktop"
)

// 自定义按钮样式
type calculatorButton struct {
	widget.Button
	bgColor     color.Color
	pressScale  float32    // 按下时的缩放比例
	isPressed   bool       // 按钮是否被按下
	animating   bool       // 是否正在动画中
}

func newCalculatorButton(label string, bgColor color.Color, tapped func()) *calculatorButton {
	button := &calculatorButton{
		bgColor:    bgColor,
		pressScale: 0.95,    // 按下时缩小到95%
		isPressed:  false,
		animating:  false,
	}
	button.ExtendBaseWidget(button)
	button.Text = label
	button.OnTapped = tapped
	return button
}

// 添加鼠标按下事件处理
func (b *calculatorButton) MouseDown(*desktop.MouseEvent) {
	b.isPressed = true
	b.animating = true
	b.Refresh()
}

// 添加鼠标释放事件处理
func (b *calculatorButton) MouseUp(*desktop.MouseEvent) {
	b.isPressed = false
	b.animating = true
	b.Refresh()
}

func (b *calculatorButton) CreateRenderer() fyne.WidgetRenderer {
	background := &canvas.Circle{
		FillColor: b.bgColor,
	}
	
	text := canvas.NewText(b.Text, color.White)
	text.TextSize = 20
	text.Alignment = fyne.TextAlignCenter

	renderer := &calculatorButtonRenderer{
		button:     b,
		background: background,
		text:       text,
		objects:    []fyne.CanvasObject{background, text},
	}

	// 创建动画
	renderer.animation = fyne.NewAnimation(
		time.Millisecond*100,    // 动画持续100毫秒
		func(progress float32) {
			if b.isPressed {
				// 从1.0缩pressScale
				scale := 1.0 - (1.0-b.pressScale)*progress
				renderer.updateScale(scale)
			} else {
				// 从pressScale恢复到1.0
				scale := b.pressScale + (1.0-b.pressScale)*progress
				renderer.updateScale(scale)
			}
			renderer.Refresh()
		},
	)

	return renderer
}

type calculatorButtonRenderer struct {
	button     *calculatorButton
	background *canvas.Circle
	text       *canvas.Text
	objects    []fyne.CanvasObject
	animation  *fyne.Animation    // 添加动画对象
}

// 添加缩放更新函数
func (r *calculatorButtonRenderer) updateScale(scale float32) {
	baseSize := fyne.NewSize(60, 45)  // 使用固定的基础大小
	scaledSize := fyne.NewSize(
		float32(baseSize.Width)*scale,
		float32(baseSize.Height)*scale,
	)
	
	// 计算偏移以保持按钮居中
	offset := fyne.NewPos(
		(float32(baseSize.Width)-scaledSize.Width)/2,
		(float32(baseSize.Height)-scaledSize.Height)/2,
	)
	
	r.background.Resize(scaledSize)
	r.background.Move(offset)
	
	// 更新文本位置
	textSize := r.text.MinSize()
	r.text.Resize(textSize)
	r.text.Move(fyne.NewPos(
		(baseSize.Width-textSize.Width)/2,
		(baseSize.Height-textSize.Height)/2,
	))
}

// 修改 Refresh 函数
func (r *calculatorButtonRenderer) Refresh() {
	if r.button.animating {
		r.animation.Start()
		r.button.animating = false
	}
	
	r.background.FillColor = r.button.bgColor
	r.background.Refresh()
	r.text.Text = r.button.Text
	r.text.Refresh()
}

// 修改 Destroy 函数
func (r *calculatorButtonRenderer) Destroy() {
	r.animation.Stop()
}

// 添加Layout方法
func (r *calculatorButtonRenderer) Layout(size fyne.Size) {
	// 设置背景大小和位置
	r.background.Resize(size)
	
	// 文本居中
	textSize := r.text.MinSize()
	r.text.Resize(textSize)
	r.text.Move(fyne.NewPos(
		(size.Width-textSize.Width)/2,
		(size.Height-textSize.Height)/2,
	))
}

// 添加MinSize方法
func (r *calculatorButtonRenderer) MinSize() fyne.Size {
	return fyne.NewSize(60, 45)
}

// 添加Objects方法
func (r *calculatorButtonRenderer) Objects() []fyne.CanvasObject {
	return r.objects
}

// 添加自定义显示组件
type calculatorDisplay struct {
	widget.BaseWidget
	text string
	process string  // 添加计算过程
}

func newCalculatorDisplay() *calculatorDisplay {
	display := &calculatorDisplay{text: "0", process: ""}
	display.ExtendBaseWidget(display)
	return display
}

func (d *calculatorDisplay) CreateRenderer() fyne.WidgetRenderer {
	result := canvas.NewText(d.text, color.White)
	result.TextSize = 32
	result.Alignment = fyne.TextAlignTrailing

	process := canvas.NewText(d.process, color.Gray{Y: 180})  // 灰色显示计算过程
	process.TextSize = 20
	process.Alignment = fyne.TextAlignTrailing

	return &calculatorDisplayRenderer{
		display: d,
		result:  result,
		process: process,
		objects: []fyne.CanvasObject{result, process},
	}
}

type calculatorDisplayRenderer struct {
	display *calculatorDisplay
	result  *canvas.Text
	process *canvas.Text
	objects []fyne.CanvasObject
}

func (r *calculatorDisplayRenderer) MinSize() fyne.Size {
	return fyne.NewSize(280, 70)  // 增加高度以容纳两行文本
}

func (r *calculatorDisplayRenderer) Layout(size fyne.Size) {
	processHeight := float32(25)
	r.process.Resize(fyne.NewSize(size.Width, processHeight))
	r.process.Move(fyne.NewPos(0, 0))
	
	r.result.Resize(fyne.NewSize(size.Width, size.Height-processHeight))
	r.result.Move(fyne.NewPos(0, processHeight))
}

func (r *calculatorDisplayRenderer) Refresh() {
	r.result.Text = r.display.text
	r.process.Text = r.display.process
	r.result.Refresh()
	r.process.Refresh()
}

func (r *calculatorDisplayRenderer) Objects() []fyne.CanvasObject {
	return r.objects
}

func (r *calculatorDisplayRenderer) Destroy() {}

func main() {
	a := app.New()
	w := a.NewWindow("计算器")
	w.SetFixedSize(true)

	// 设置深色主题
	a.Settings().SetTheme(theme.DarkTheme())

	// 声明计算器状态变量
	var (
		firstNumber float64
		operation   string
		newNumber   = true
		showingResult = false  // 添加这个变量
	)

	// 使用新的显示组件替代原来的Entry
	display := newCalculatorDisplay()

	// 定义颜色
	grayColor := &color.NRGBA{R: 51, G: 51, B: 51, A: 255}
	orangeColor := &color.NRGBA{R: 255, G: 159, B: 10, A: 255}
	lightGrayColor := &color.NRGBA{R: 165, G: 165, B: 165, A: 255}
	darkerGrayColor := &color.NRGBA{R: 40, G: 40, B: 40, A: 255}

	// 数字按钮
	numbers := map[string]*calculatorButton{}
	for i := 0; i <= 9; i++ {
		number := i
		numbers[strconv.Itoa(i)] = newCalculatorButton(strconv.Itoa(i), grayColor, func() {
			if newNumber || showingResult {
				display.text = ""
				if showingResult {
					display.process = ""  // 清除之前的计算过程
				}
				newNumber = false
				showingResult = false
			}
			display.text += strconv.Itoa(number)
			display.Refresh()
		})
	}

	// 运算符按钮
	add := newCalculatorButton("+", orangeColor, func() {
		if showingResult {
			firstNumber, _ = strconv.ParseFloat(display.text, 64)
			display.process = display.text + " +"  // 开始新的计算过程
			showingResult = false
		} else {
			if !newNumber {
				secondNumber, _ := strconv.ParseFloat(display.text, 64)
				firstNumber = calculateResult(firstNumber, secondNumber, operation)
				display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)
				display.process = display.text + " +"  // 更新计算过程
			} else {
				firstNumber, _ = strconv.ParseFloat(display.text, 64)
				display.process = display.text + " +"  // 显示第一个数字和运算符
			}
		}
		operation = "+"
		newNumber = true
		display.Refresh()
	})

	subtract := newCalculatorButton("-", orangeColor, func() {
		if showingResult {
			firstNumber, _ = strconv.ParseFloat(display.text, 64)
			showingResult = false
		} else {
			if !newNumber {
				secondNumber, _ := strconv.ParseFloat(display.text, 64)
				firstNumber = calculateResult(firstNumber, secondNumber, operation)
				display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)
			} else {
				firstNumber, _ = strconv.ParseFloat(display.text, 64)
			}
		}
		operation = "-"
		newNumber = true
		display.Refresh()
	})

	multiply := newCalculatorButton("×", orangeColor, func() {
		if showingResult {
			firstNumber, _ = strconv.ParseFloat(display.text, 64)
			showingResult = false
		} else {
			if !newNumber {
				secondNumber, _ := strconv.ParseFloat(display.text, 64)
				firstNumber = calculateResult(firstNumber, secondNumber, operation)
				display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)
			} else {
				firstNumber, _ = strconv.ParseFloat(display.text, 64)
			}
		}
		operation = "*"
		newNumber = true
		display.Refresh()
	})

	divide := newCalculatorButton("÷", orangeColor, func() {
		if showingResult {
			firstNumber, _ = strconv.ParseFloat(display.text, 64)
			showingResult = false
		} else {
			if !newNumber {
				secondNumber, _ := strconv.ParseFloat(display.text, 64)
				firstNumber = calculateResult(firstNumber, secondNumber, operation)
				display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)
			} else {
				firstNumber, _ = strconv.ParseFloat(display.text, 64)
			}
		}
		operation = "/"
		newNumber = true
		display.Refresh()
	})

	equals := newCalculatorButton("=", orangeColor, func() {
		if !newNumber {
			secondNumber, _ := strconv.ParseFloat(display.text, 64)
			display.process += " " + display.text + " ="  // 完成计算过程
			result := calculateResult(firstNumber, secondNumber, operation)
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			firstNumber = result
			showingResult = true
			display.Refresh()
		}
	})

	// 额外的功能按钮
	ac := newCalculatorButton("AC", lightGrayColor, func() {
		display.text = "0"
		display.process = ""  // 清除计算过程
		firstNumber = 0
		operation = ""
		newNumber = true
		showingResult = false
		display.Refresh()
	})

	plusMinus := newCalculatorButton("+/-", lightGrayColor, func() {
		if current, err := strconv.ParseFloat(display.text, 64); err == nil {
			display.text = strconv.FormatFloat(-current, 'f', -1, 64)
			display.Refresh()
		}
	})

	percent := newCalculatorButton("%", lightGrayColor, func() {
		if current, err := strconv.ParseFloat(display.text, 64); err == nil {
			display.text = strconv.FormatFloat(current/100, 'f', -1, 64)
			display.Refresh()
		}
	})

	decimal := newCalculatorButton(".", grayColor, func() {
		if !strings.Contains(display.text, ".") {
			display.text += "."
			display.Refresh()
		}
	})

	// 科学计算器的额外功能按钮
	mc := newCalculatorButton("mc", darkerGrayColor, func() {
		// 内存清除功能
	})

	mPlus := newCalculatorButton("m+", darkerGrayColor, func() {
		// 内存加功能
	})

	mMinus := newCalculatorButton("m-", darkerGrayColor, func() {
		// 内存减功能
	})

	mr := newCalculatorButton("mr", darkerGrayColor, func() {
		// 内存调用功能
	})

	// 科学运算按钮
	sin := newCalculatorButton("sin", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			result := math.Sin(val * math.Pi / 180) // 转换为弧度
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	cos := newCalculatorButton("cos", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			result := math.Cos(val * math.Pi / 180)
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	tan := newCalculatorButton("tan", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			result := math.Tan(val * math.Pi / 180)
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	ln := newCalculatorButton("ln", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			result := math.Log(val)
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	log := newCalculatorButton("log₁₀", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			result := math.Log10(val)
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	sqrt := newCalculatorButton("√x", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			result := math.Sqrt(val)
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	square := newCalculatorButton("x²", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			result := math.Pow(val, 2)
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	pi := newCalculatorButton("π", darkerGrayColor, func() {
		display.text = strconv.FormatFloat(math.Pi, 'f', -1, 64)
		display.Refresh()
	})

	e := newCalculatorButton("e", darkerGrayColor, func() {
		display.text = strconv.FormatFloat(math.E, 'f', -1, 64)
		display.Refresh()
	})

	factorial := newCalculatorButton("x!", darkerGrayColor, func() {
		if val, err := strconv.ParseFloat(display.text, 64); err == nil {
			n := int(val)
			result := 1.0
			for i := 2; i <= n; i++ {
				result *= float64(i)
			}
			display.text = strconv.FormatFloat(result, 'f', -1, 64)
			display.Refresh()
		}
	})

	// 添加模式切换状态
	var isScientificMode = false
	
	// 声明updateLayout变量(在最前面)
	var updateLayout func()
	
	// 创建主容器
	mainContainer := container.NewVBox()
	
	// 创建显示区域容器
	displayContainer := container.NewPadded(display)
	
	// 创建基本计算器布局
	createBasicLayout := func() *fyne.Container {
		return container.NewGridWithColumns(4,
			ac, plusMinus, percent, divide,
			numbers["7"], numbers["8"], numbers["9"], multiply,
			numbers["4"], numbers["5"], numbers["6"], subtract,
			numbers["1"], numbers["2"], numbers["3"], add,
			numbers["0"], decimal, equals,
		)
	}

	// 创建科学计算器布局
	createScientificLayout := func() *fyne.Container {
		return container.NewGridWithColumns(10,
			// 第一行
			newCalculatorButton("(", darkerGrayColor, nil),
			newCalculatorButton(")", darkerGrayColor, nil),
			mc, mPlus, mMinus, mr,
			ac, plusMinus, percent, divide,
			// 第二行
			newCalculatorButton("2ⁿᵈ", darkerGrayColor, nil),
			square,
			newCalculatorButton("x³", darkerGrayColor, nil),
			newCalculatorButton("xʸ", darkerGrayColor, nil),
			e,  // 使用 e 按钮
			newCalculatorButton("10ˣ", darkerGrayColor, nil),
			numbers["7"], numbers["8"], numbers["9"], multiply,
			// 第三行
			factorial,  // 使用阶乘按钮
			sqrt,      // 使用平方根按钮
			pi,        // 使用 π 按钮
			ln,        // 使用自然对数按钮
			log,       // 使用常用对数按钮
			newCalculatorButton("EE", darkerGrayColor, nil),
			numbers["4"], numbers["5"], numbers["6"], subtract,
			// 第四行
			sin,       // 使用正弦按钮
			cos,       // 使用余弦按钮
			tan,       // 使用正切按钮
			newCalculatorButton("sinh", darkerGrayColor, nil),
			newCalculatorButton("cosh", darkerGrayColor, nil),
			newCalculatorButton("tanh", darkerGrayColor, nil),
			numbers["1"], numbers["2"], numbers["3"], add,
			// 第五行
			newCalculatorButton("Rad", darkerGrayColor, nil),
			newCalculatorButton("sinh⁻¹", darkerGrayColor, nil),
			newCalculatorButton("cosh⁻¹", darkerGrayColor, nil),
			newCalculatorButton("tanh⁻¹", darkerGrayColor, nil),
			newCalculatorButton("Rand", darkerGrayColor, nil),
			newCalculatorButton("EE", darkerGrayColor, nil),
			numbers["0"], decimal, equals,
		)
	}
	
	// 创建顶部工具栏(不包含modeSwitch)
	toolbar := container.NewHBox(
		widget.NewSeparator(),
	)

	// 定义updateLayout函数
	updateLayout = func() {
		var layout fyne.CanvasObject
		if isScientificMode {
			layout = createScientificLayout()
		} else {
			layout = createBasicLayout()
		}
		
		mainContainer.Objects = []fyne.CanvasObject{
			toolbar,
			displayContainer,
			layout,
		}
		mainContainer.Refresh()
	}

	// 现在定义modeSwitch(在updateLayout之后)
	modeSwitch := newCalculatorButton("⚙", lightGrayColor, func() {
		isScientificMode = !isScientificMode
		
		startSize := w.Canvas().Size()
		var targetWidth float32
		if isScientificMode {
			targetWidth = 600
		} else {
			targetWidth = 300
		}
		targetSize := fyne.NewSize(targetWidth, 450)
		
		animation := fyne.NewAnimation(
			time.Millisecond*300,
			func(progress float32) {
				width := startSize.Width + (targetSize.Width-startSize.Width)*progress
				height := startSize.Height + (targetSize.Height-startSize.Height)*progress
				w.Resize(fyne.NewSize(width, height))
			},
		)
		
		animation.Start()
		updateLayout()
	})

	// 更新toolbar,添加modeSwitch
	toolbar.Objects = append([]fyne.CanvasObject{modeSwitch}, toolbar.Objects...)

	// 初始化布局
	updateLayout()

	// 直接使用mainContainer作为窗口内容
	w.SetContent(mainContainer)
	w.Resize(fyne.NewSize(300, 450))
	w.ShowAndRun()
}

// 添加一个辅助函数来计算结果
func calculateResult(first, second float64, op string) float64 {
	var result float64
	switch op {
	case "+":
		result = first + second
	case "-":
		result = first - second
	case "*":
		result = first * second
	case "/":
		if second != 0 {
			result = first / second
		}
	}
	return result
}

go.mod文件

module calc

go 1.23.1

require fyne.io/fyne/v2 v2.5.2

require (
	fyne.io/systray v1.11.0 // indirect
	github.com/BurntSushi/toml v1.4.0 // indirect
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/fredbi/uri v1.1.0 // indirect
	github.com/fsnotify/fsnotify v1.7.0 // indirect
	github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
	github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirect
	github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
	github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
	github.com/go-text/render v0.2.0 // indirect
	github.com/go-text/typesetting v0.2.0 // indirect
	github.com/godbus/dbus/v5 v5.1.0 // indirect
	github.com/gopherjs/gopherjs v1.17.2 // indirect
	github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 // indirect
	github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
	github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
	github.com/pmezard/go-difflib v1.0.0 // indirect
	github.com/rymdport/portal v0.2.6 // indirect
	github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
	github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
	github.com/stretchr/testify v1.8.4 // indirect
	github.com/yuin/goldmark v1.7.1 // indirect
	golang.org/x/image v0.18.0 // indirect
	golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect
	golang.org/x/net v0.25.0 // indirect
	golang.org/x/sys v0.20.0 // indirect
	golang.org/x/text v0.16.0 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
)

Go Fyne实战:5分钟快速搭建你的第一个跨平台GUI应用(附完整代码) 本文通过实战演示,指导开发者如何使用Go语言的Fyne工具集,在5分钟内快速构建首个跨平台GUI应用。文章提供了从环境搭建、编写“Hello World”程序到创建实用迷你计算器的完整代码,并详细解析了Fyne的组件、事件驱动和布局系统,最后介绍了应用的打包与分发方法,展现了Fyne在简化跨平台桌面开发方面的强大能力。 阅读详情

相关推荐

Go语言的图形用户界面

在Go语言中,有几个比较常用的GUI库,它们各具特点,适合不同的应用场景。

2501_90485657的博客 1222

fyne的使用-go语言GUI库

Fyne 是一个使用 Go 编写的易于使用的 UI 工具包和应用程序 API。它旨在构建使用单一代码库在桌面和移动设备上运行的应用程序。2.3 版是 Fyne API 的当前版本,它添加了改进的主题设计、云存储、改进的国际语言文本处理和许多较小的功能添加。github地址:https://github.com/fyne-io/fyne要使用Fyne开发应用,你需要Go 1.14或更高版本,C编译器和系统开发工具。

Apostoli的博客 5230

golang GUI图形界面框架fyne演示例子

golang GUI图形界面框架fyne演示例子,可以同时查看源码和效果

GO GUI之fyne实例(安装配置和实例代码)

go的gui框架fyne实战开发。中文汉化。界面编排。

weixin_42773635的博客 1万+

RustFS vs MinIO:深入对比分布式存储的性能、功能与选型指南

RustFS与MinIO是两款热门分布式存储系统,分别针对高性能与通用场景设计。RustFS基于Rust语言,在吞吐量(最高提升46%)、延迟(降低37%)和资源效率(内存占用减少67%)上显著优于MinIO,适合AI训练、金融级应用等高性能需求。MinIO凭借成熟的S3兼容性、云原生集成和企业级功能,更适用于混合云及现有S3生态。许可方面,RustFS采用Apache 2.0,MinIO为AGPLv3。选型建议:优先RustFS应对性能敏感场景,选择MinIO注重生态兼容性,也可考虑混合架构策略。

分布式存储与RustFS的博客 2024

【Hyper-V】虚拟机网络配置全解析:从端口映射到固定IP实战

本文全面解析Hyper-V虚拟机网络配置,从理解虚拟交换机三种模式(外部、内部、专用)的底层逻辑入手,指导用户创建稳定的内部/NAT网络,并详细演示如何在Linux与Windows虚拟机中配置固定IP。文章进一步深入讲解端口映射原理与netsh命令实战,以及双网卡配置和PowerShell自动化脚本等高级技巧,帮助用户彻底解决虚拟机网络“失联”问题,实现灵活可控的网络环境。

weixin_29290947的博客 269

go fyne 跨平台开发框架 gui 编程 抖音下载 去水印编程 学习交流

package filetool import ( "os" "path/filepath" "strings" ) /* 获取程序运行路径 */ func GetCurrentDirectory() string { dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { } retur...

fj_ut的博客 3475

村田电感模型选型指南:.s2p和SPICE netlist在ADS中的表现差异

本文深度解析了村田电感在ADS仿真中.s2p与SPICE netlist两种模型的表现差异。通过对比模型本质、仿真设置及高低频段精度,揭示了.s2p文件基于实测插值而SPICE netlist基于等效电路外推的特性。文章提供了明确的选型策略,帮助工程师根据项目频段、仿真类型和精度需求,在射频与微波电路设计中做出最优模型选择。

k9l0m1的博客 452

[golang gui]fyne框架代码示例

fyne

三巧的博客 2586

云漾AI创作平台实战:如何用GPT4.0+Midjourney快速生成商业级插画(附Prompt模板)

本文详细介绍了如何利用云漾AI创作平台结合GPT4.0和Midjourney快速生成商业级插画。通过智能文案生成与视觉化工作流,大幅提升创作效率,适用于电商、社交媒体等多种场景。文章包含实用Prompt模板和参数调整技巧,帮助设计师和内容创作者高效产出专业插画。

weixin_29251567的博客 219

Ubuntu零基础入门到精通【4.4讲】:网络、蓝牙、显示器、声音与输入法设置!

🏆 本文收录于 《滚雪球学 Ubuntu》 专栏。 本专栏面向有一定计算机基础,但尚未系统学习 Linux / Ubuntu 的读者,采用“滚雪球式学习法”:先装好、再会用、再理解、再优化、再实战,带你从第一次进入 Ubuntu 桌面 / 终端开始,逐步掌握 Ubuntu 的日常使用、命令操作、软件安装、系统配置、开发环境搭建与服务器部署能力。

**My Coding Family** 1486

Go 每日一库:fyne 库,Go GUI 开发新体验

你是否还在为 Go 语言缺乏便捷的 GUI 开发方案而烦恼?尝试过各种跨平台 GUI 库却被复杂的配置和不统一的接口劝退?今天我们将介绍一款专为 Go 设计的现代化 GUI 框架——fyne 库,它让 Go 开发者能够以极少的代码创建出美观、一致的跨平台桌面应用。通过本文,你将掌握 fyne 的核心概念、布局系统和组件使用,最终能独立开发简单的桌面应用。 ## 什么是 fyne fyne 是一...

gitblog_00094的博客 1301

带洞多边形如何分成凸多边形集合,对多边形进行凸分解?

摘要: 凸分解是计算几何中的经典问题,分为三角化和凸分解两种方法。三角化将带洞多边形转换为简单多边形并分割为三角形,常用算法包括耳剪法、单调多边形三角化等。凸分解则生成更少但更大的凸多边形,常用Hertel-Mehlhorn算法或基于凹点的递归切割。实际应用中建议使用CGAL、Poly2Tri等成熟库处理。三角化适合图形渲染,凸分解更适用于物理引擎和路径规划。关键步骤包括数据校验、选择合适的算法及后处理优化。

插件开发 355

Golang WebView:打造跨平台的桌面应用_go webview

本文介绍了Golang WebView的特点和使用方法,并探讨了它在实际项目中的应用。Golang WebView是一个强大的桌面应用库,允许开发人员使用Web技术来构建跨平台的应用。它具有简单易用、功能强大和高性能等特点,适用于各种类型的应用开发场景。希望本文对您了解Golang WebView的特点和应用有所帮助,鼓励更多的开发者在桌面应用领域中探索和应用Golang技术。

2401_87198107的博客 1618

linux内核学习(一)---内核社区介绍及补丁提交

本系列开始会对linux内核进行系统性的学习,以源码与内核社区为基础,了解前沿的内核机制,同时也深度了解linux内核中的一些经典机制 本章会先对linux内核社区进行简单的介绍,包括源码下载、内核社区的修改提交

文艺小少年的博客 536

基于CutLSTM-ATT 模型的刀具磨损预测-【一个月之内发一篇中文核心辅导】

基于CutLSTM-ATT 模型的刀具磨损预测-【一个月之内发一篇中文核心辅导】

315

Fyne实战:用Go语言5分钟搭建一个跨平台计算器(附完整代码)

本文详细介绍了如何使用Go语言和Fyne GUI库,在短短5分钟内快速构建一个功能完整的跨平台桌面计算器。通过分步教程,开发者可以掌握Fyne的核心概念,包括窗口创建、组件布局、事件绑定以及应用打包,体验Go语言在桌面应用开发中的高效与便捷。

weixin_29275257的博客 297

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【Go语言】Fyne GUI 高级开发实战:从组件定制到主题优化

本文深入探讨了Go语言Fyne GUI框架的高级开发技巧,旨在帮助开发者突破基础应用限制。通过实战案例详细解析了如何从零构建自定义组件(如环形进度条)以及深度定制主题系统,从而打造专业、独特且高性能的桌面应用程序。掌握这些高级特性是提升应用专业性和用户体验的关键。

pz890123的博客 843

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

golang开发GUI桌面应用fyne(五)- 计算器

golang开发GUI桌面应用fyne(五)- 计算器

猛犸象 1281

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

探索与体验:Fyne 开源项目实例库

探索与体验:Fyne 开源项目实例库 在当今的软件开发领域,拥有强大且易于使用的工具包至关重要。Fyne 库便是一个这样的工具,它为构建优美而响应迅速的跨平台 GUI 程序提供了便利。而 fyne-examples 是 Fyne 社区精心准备的一系列示例应用,它们展示了 Fyne 的功能和潜力,帮助开发者快速上手并掌握这一先进 UI 工具。 项目介绍 fyne-examples 项目旨在通过各种类...

gitblog_00044的博客 697

用Python构建桌面环境模拟器:从零实现图形化伪操作系统

操作系统是计算机系统的核心软件,负责管理硬件资源并提供用户交互界面。其基本原理包括进程管理、内存分配、文件系统和设备驱动等核心模块。在技术学习路径中,通过模拟操作系统用户界面层,可以高效串联GUI编程、事件驱动模型和模块化设计等核心概念。这类项目常被称为“Shell”或“桌面环境模拟器”,它作为运行在宿主操作系统之上的应用程序,为初学者提供了绝佳的综合实践场景。使用Python的Tkinter等框架实现图形化桌面、应用管理和文件模拟,不仅能深化对事件驱动编程和状态管理的理解,还能帮助开发者建立清晰的软件工程

weixin_33889665的博客 400

golang学习之go fyne GUI编程

go语言图像界面编程 go GUI 库 fyne 三角函数绘制时钟

weixin_56349119的博客 4496

Fyne ( go跨平台GUI )中文文档-Fyne总览(二)

本文档注意参考官网() 编写, 只保留基本用法go代码展示为Go 1.16及更高版本,ide为。

bugtraq的博客 3629

发现用 Go 写桌面程序真的太爽了...

废话不多说,先看效果,我已经安装到 macOS 了。它是如何构建的?答案是:Fyne 库的魔力。什么是 Fyne?Fyne 是一个用 Go 语言编写的跨平台 GUI 库,它允许开发者使用 Go 语言快速构建具有原生外观和感觉的桌面应用程序。Fyne 的设计理念是简单、易用,同时提供丰富的组件和灵活的布局选项,使得开发者能够专注于应用逻辑,而不必担心界面设计的复杂性。特点:跨平台支持:一次编写,应用...

新亮笔记 5805

Go Fyne:一种现代的,跨平台的 GUI 开发工具集

Fyne 提供了一种简单而直观的方式来构建应用程序,并且注意到它是跨平台的,可以在 Windows,macOS,Linux,Android 和 iOS 上运行。它提供了丰富的组件库,强大的布局系统,灵活的主题和样式,以及强大的事件处理和动画系统。它摒弃了过时的复杂系统,而是采用了现代化的,基于对象的方法。丰富的组件库:Fyne 提供了一套丰富的预定义组件,包括但不限于按钮,复选框,文本框,列表,菜单,以及滑块等。小部件(Widgets):小部件是 Fyne 的基础组件,例如按钮,标签,文本框,列表等。

鑫和皓的博客 3271
上一篇: 医院三级质控信息化支撑工具之一
下一篇: Hasura 中间件API go操作示例
布林模型
博客等级 码龄15年 61粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值