You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现点击按钮生成并打印QR二维码图片

功能实现方案

调整后的完整代码

已补全空安全适配、蓝牙打印逻辑、二维码分享功能的完整实现:

// 先将依赖添加到pubspec.yaml
// qr_flutter: ^4.1.0
// blue_thermal_printer: ^1.1.5
// share_plus: ^7.2.1
// path_provider: ^2.1.0
// screenshot: ^2.1.0 用于将二维码组件转成图片供打印/分享使用

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:share_plus/share_plus.dart';
import 'package:blue_thermal_printer/blue_thermal_printer.dart';
import 'package:screenshot/screenshot.dart';
import 'package:path_provider/path_provider.dart';
import '../../../routes.dart';

class GenerateClipboard extends StatefulWidget {
  final String dataa;
  const GenerateClipboard({super.key, required this.dataa});

  @override
  State<GenerateClipboard> createState() => _GenerateClipboardState();
}

class _GenerateClipboardState extends State<GenerateClipboard> {
  final ScreenshotController _screenshotController = ScreenshotController();
  BlueThermalPrinter printer = BlueThermalPrinter.instance;
  List<BluetoothDevice> _devices = [];
  bool _isConnected = false;

  @override
  void initState() {
    super.initState();
    _getBondedDevices();
    // 监听蓝牙连接状态
    printer.onStateChanged().listen((state) {
      setState(() {
        _isConnected = state == BlueThermalPrinter.STATE_CONNECTED;
      });
    });
  }

  // 获取已经配对的蓝牙设备列表
  void _getBondedDevices() async {
    _devices = await printer.getBondedDevices();
    setState(() {});
  }

  // 二维码打印逻辑
  void _handlePrint() async {
    if (!_isConnected) {
      _showDeviceSelectDialog();
      return;
    }
    final qrImageBytes = await _screenshotController.capture();
    if (qrImageBytes != null) {
      printer.printImageBytes(qrImageBytes);
      printer.paperCut();
    }
  }

  // 二维码分享逻辑
  void _handleShare() async {
    final qrImageBytes = await _screenshotController.capture();
    if (qrImageBytes != null) {
      final tempDir = await getTemporaryDirectory();
      final tempFile = await File('${tempDir.path}/generated_qr.png').create();
      await tempFile.writeAsBytes(qrImageBytes);
      Share.shareXFiles([XFile(tempFile.path)], text: '生成的二维码内容');
    }
  }

  // 蓝牙设备选择弹窗
  Future<void> _showDeviceSelectDialog() async {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('选择已配对的打印机'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: _devices.map((device) {
            return ListTile(
              title: Text(device.name ?? '未知蓝牙设备'),
              onTap: () async {
                await printer.connect(device);
                if (mounted) Navigator.pop(context);
              },
            );
          }).toList(),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: MediaQuery.of(context).size.height,
        decoration: const BoxDecoration(
          image: DecorationImage(
            image: AssetImage("assets/images/bg_all.png"),
            fit: BoxFit.fill,
          ),
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Padding(
              padding: const EdgeInsets.only(top: 20, left: 20),
              child: Stack(
                children: [
                  Align(
                    alignment: Alignment.centerLeft,
                    child: InkWell(
                      child: const Icon(Icons.arrow_back_ios),
                      onTap: () {
                        Navigator.pushReplacementNamed(
                            context, MyRoutes.clipboard);
                      },
                    ),
                  ),
                  const Align(
                    alignment: Alignment.center,
                    child: Text("生成二维码",
                        textAlign: TextAlign.center,
                        style: TextStyle(fontSize: 20)),
                  )
                ],
              ),
            ),
            const SizedBox(height: 20),
            // 截图组件包裹二维码,方便转成图片
            Screenshot(
              controller: _screenshotController,
              child: QrImage(
                data: widget.dataa,
                version: QrVersions.auto,
                size: 250,
                backgroundColor: Colors.white,
              ),
            ),
            const SizedBox(height: 60),
            Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  InkWell(
                    onTap: _handlePrint,
                    child: Image.asset("assets/images/wifi/print.png",
                        height: 100, width: 100),
                  ),
                  InkWell(
                      onTap: _handleShare,
                      child: Image.asset("assets/images/wifi/export.png",
                          height: 100, width: 100)),
                ]),
            // 连接状态提示
            if (_isConnected)
              const Padding(
                padding: EdgeInsets.only(top: 20),
                child: Text(
                  '打印机已连接',
                  style: TextStyle(color: Colors.green, fontSize: 14),
                ),
              )
          ],
        ),
      ),
    );
  }
}

触发二维码生成的按钮逻辑

在需要唤起二维码生成页面的位置,给按钮绑定点击事件,传入对应字段内容即可:

ElevatedButton(
  onPressed: (){
    // 替换为你需要生成二维码的字段内容
    String targetContent = "自定义字段内容";
    Navigator.push(context, MaterialPageRoute(builder: (context)=> GenerateClipboard(dataa: targetContent)));
  },
  child: const Text("生成二维码")
)

权限配置

  • 安卓端需要在AndroidManifest.xml添加蓝牙相关权限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 安卓12及以上额外权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
  • iOS端需要在Info.plist添加蓝牙权限说明:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>需要蓝牙权限连接热敏打印机</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>需要蓝牙权限连接热敏打印机</string>

注意:打印机需要先和手机完成蓝牙配对,才会出现在可连接设备列表中

内容的提问来源于stack exchange,提问作者Hamza Malik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 22:54:03