-
如何开发一个如图的时间管理的小程序?
2019-12-07 19:59:30求告知,因为一直没有搜索到类似的小程序,而且小程序的功能按照我的理解是基于网页结构,但是我也没搜索到类似的网页  ![图片... -
【中国大学MOOC】java程序设计-week11-编写一个具有图形用户界面的应用程序
2020-10-08 11:09:37可以是一个小游戏程序,也可以是一个日常的应用程序(如个人收支管理),也可以是一个多媒体方面的应用程序。可以任意选题,但要注意以下几点: (1)具有图形用户界面,使用JFrame/JButton等窗体及组件。 (2)具有...1.题目
结合本讲及前面几讲的内容,编写一个具有图形用户界面的应用程序。可以是一个小游戏程序,也可以是一个日常的应用程序(如个人收支管理),也可以是一个多媒体方面的应用程序。可以任意选题,但要注意以下几点:
(1)具有图形用户界面,使用JFrame/JButton等窗体及组件。
(2)具有绘图、图像或音频、视频方面的功能。
(3)具有文件读取或数据库访问方面的功能。
可以参考我们的示例,也可以参考网上的其他示例,但要求进行改进或重写,如果是改进,则要指出哪些部分是你的改进。希望你能做出有一定综合性的应用程序来。
评分标准:
程序能正常运行,具有较好的可用性(2分);
具有图形用户界面,使用swing的组件(3分);
具有绘图、图像或音频、视频方面的功能(2分);
具有文件读取或数据库访问方面的功能(2分);
具有一定的创意或总体评价较高(1分)。
2.题解
package homework11; import java.io.File; import java.io.FileReader; import javax.swing.table.DefaultTableModel; import java.util.Vector; import java.awt.*; import javax.swing.*; /** * 个人收支记账本--应用程序 * 功能:1. 读取txt文件中记录的用户的收支情况并显示; * 2. 插入收支情况记录表,系统自动计算该用户的结余金额。 * 配置&使用方法:将homework11压缩包解压缩,添加到项目src文件夹下,直接点击运行; * 点击“选择文本文件载入”,(默认路径为D盘)选择本文件夹下的file.txt,即可显示收支情况; * 点击"插入收支记录",填写收入,支出(均为Double类型),系统自动更新计算结余金额。 * 文件说明:homework11.java:项目代码; * file.txt: 用户的收支情况txt记录文件; * image.jpg: 用户的头像; * 采用技术:1. Swing下JFrame/JButton的窗体及组件 图形化用户界面; * 2. 图像读取并显示功能:ImageIcon函数; * 3. txt文件读取功能,自主选择文件; * 4. 自动计算结余金额,根据上一次的结余金额,本次的收入,支出,计算新的一轮结余金额; * 5. 定义个人情况为Users类,保护数据隐私,方便数据读取。 */ public class homework11 extends JFrame { private JFrame frame = null; private File file = null; private FileReader fileReader = null; private JFileChooser fileChooser = null; private JLabel image = null; private JLabel title = null; private JButton loadin = null; private DefaultTableModel tableModel = null; private JTable table = null; private JButton btnInsert = null; public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(() -> { new homework11(); }); } public homework11() { initialize(); } private void initialize() { JPanel pnlTop = new JPanel(); ImageIcon img = new ImageIcon("src\\homework11\\image.jpg"); img.setImage(img.getImage().getScaledInstance(30,30,Image.SCALE_DEFAULT)); image = new JLabel(img); title = new JLabel("个人收支管理", JLabel.CENTER); loadin = new JButton("选择文本文件载入"); pnlTop.add(image); pnlTop.add(title); pnlTop.add(loadin); tableModel = new DefaultTableModel(); table=new JTable(tableModel); JPanel pnlBottom = new JPanel(); btnInsert = new JButton("插入收支记录"); pnlBottom.add(btnInsert); frame = new JFrame("个人收支管理"); frame.add(pnlTop, BorderLayout.NORTH); frame.add(new JScrollPane(table), BorderLayout.CENTER); frame.add(pnlBottom, BorderLayout.SOUTH); loadin.addActionListener(e -> doLoadin()); btnInsert.addActionListener(e -> doInsert()); frame.setSize(500, 500); frame.setLocation(300, 150); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } /** * 载入收支记录文本文件 */ private void doLoadin() { fileChooser=new JFileChooser("D:\\"); if(fileChooser.showOpenDialog(frame)==JFileChooser.APPROVE_OPTION) { file=fileChooser.getSelectedFile(); try { fileReader=new FileReader(file); Vector<String> vector=new Vector<String>(); vector.add("ID");vector.add("姓名");vector.add("收入");vector.add("支出");vector.add("结余"); Vector<Vector<String>> dataVector=new Vector<Vector<String>>(); Vector<String> dataVector2=new Vector<String>(); String string=""; while(fileReader.ready()) { char ch=(char) fileReader.read(); if(ch==' ') { dataVector2.add(string); string=""; } else if(ch=='\n') { dataVector2.add(string); string=""; dataVector.add(dataVector2); dataVector2=new Vector<String>(); } else { string=string+ch; } } tableModel.setDataVector(dataVector, vector); } catch (Exception e) { e.printStackTrace(); } } } /** * 插入收支记录 */ private void doInsert(){ double lastsurplus = Double.parseDouble(tableModel.getValueAt(tableModel.getRowCount()-1, tableModel.getColumnCount()-1).toString()); ContactsDetailDialog inputDialog = new ContactsDetailDialog(); inputDialog.uiClear(); inputDialog.setVisible(true); System.out.println(inputDialog.isOkPressed()); if (!inputDialog.isOkPressed()) return; Users inputContact = inputDialog.ui2entity(); System.out.println(inputContact); Vector<String> newdataVector=new Vector<String>(); newdataVector.add(tableModel.getValueAt(tableModel.getRowCount()-1, 0).toString()); newdataVector.add(tableModel.getValueAt(tableModel.getRowCount()-1, 1).toString()); newdataVector.add(inputContact.getIncome().toString()); newdataVector.add(inputContact.getExpense().toString()); newdataVector.add(String.valueOf((lastsurplus+inputContact.getIncome()-inputContact.getExpense()))); tableModel.addRow(newdataVector); } } /** * 插入界面 */ class ContactsDetailDialog extends JDialog { boolean okPressed = false; private JLabel lblIncome = null; private JTextField txtIncome = null; private JLabel lblExpense = null; private JTextField txtExpense = null; private JPanel pnlInput = null; private JPanel pnlButtons = null; private JButton btnOk = null; private JButton btnCancel = null; public ContactsDetailDialog() { lblIncome = new JLabel("收入"); txtIncome = new JTextField(); lblExpense = new JLabel("支出"); txtExpense = new JTextField(); pnlInput = new JPanel(); pnlInput.setLayout(new GridLayout(2, 2)); pnlInput.add(lblIncome); pnlInput.add(txtIncome); pnlInput.add(lblExpense); pnlInput.add(txtExpense); pnlButtons = new JPanel(); btnOk = new JButton("Ok"); btnCancel = new JButton("Cancel"); pnlButtons.setLayout(new FlowLayout(FlowLayout.CENTER)); pnlButtons.add(btnOk); pnlButtons.add(btnCancel); getContentPane().setLayout(new BorderLayout()); getContentPane().add(pnlInput, BorderLayout.CENTER); getContentPane().add(pnlButtons, BorderLayout.SOUTH); setSize(300, 150); this.setModal(true); setLocationRelativeTo(null); setDefaultCloseOperation(DISPOSE_ON_CLOSE); btnOk.addActionListener(e -> { okPressed = true; dispose(); }); btnCancel.addActionListener(e -> { okPressed = false; dispose(); }); } public boolean isOkPressed() { return okPressed; } public Users ui2entity() { Users c = new Users(); c.setIncome(Double.parseDouble(txtIncome.getText())); c.setExpense(Double.parseDouble(txtExpense.getText())); return c; } public void uiClear() { txtIncome.setText(""); txtExpense.setText(""); } } /** * 个人收支情况类 */ class Users { private int id; private String name = null; private Double income = null; private Double expense = null; private Double surplus = null; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getIncome() { return income; } public void setIncome(Double income) { this.income = income; } public Double getExpense() { return expense; } public void setExpense(Double expense) { this.expense = expense; } public Double getSurplus() { return surplus; } public void setSurplus(Double surplus) { this.surplus = surplus; } }
如果感觉对你有所帮助,不妨点个赞,关注一波,激励博主持续更新!
-
如何做一个小程序口令红包功能
2018-01-10 00:00:00在做小程序后端支持的过程中遇到不少有意思的功能,有些比较考你的思维散发及解决问题的实际能力,这里摘录一下记录下来,是为抛砖引玉、如能帮到别人,自然是最好不过了。先放几张设计图看下大概功能:大概便是如此...在做小程序后端支持的过程中遇到不少有意思的功能,有些比较考你的思维散发及解决问题的实际能力,这里摘录一下记录下来,是为抛砖引玉、如能帮到别人,自然是最好不过了。
先放几张设计图看下大概功能:
大概便是如此。
通过图片可以看到,涉及到的稍微复杂一点的功能点有:语音文字识别、红包分配算法,周边红包算法等等。 其余的都是些简单的CRUD操作。我CODING+TESTING用了差不多一周,以下说下各个功能点的大概实现思路及方法。
语音识别
应用场景:A用户设置了一个中文的口令红包,接收到该红包的B用户需要用语音说出该口令,完全匹配的话则获取该红包的某个比例金额。
录音自然是调用小程序提供的原生接口,不过这里比较坑的是微信的录音格式是 .silk。网上搜索的方法是先将.silk格式转成wav或者MP3格式,然后再调用各大云服务平台的接口实现语音识别功能。
这里使用了 https://github.com/kn007/silk-v3-decoder 提供的库用来转成wav格式,然后使用百度的语音识别开放接口 https://ai.baidu.com/tech/speech/asr 来识别语音结果。
业务实现步骤如下:
1.前端实现录音功能 2.upload接口上传.silk语音文件,入库 3.触发语音识别task,返回成功给前端(异步) 4.前端轮询识别结果。
因为从上传到识别到返回结果是一个耗时操作,所以识别过程最好是异步操作。(第三步)
upload语音接口部分代码:
// ... 业务代码略
$voice = $this->getCreatedVoiceByBody(); // 上传并入库
$this->identifyVoice($voice); // 触发语音识别task
// ...
public function identifyVoice($voice)
{
WorkerUtil::sendTaskByRouteAndParams('task/detectvoice', ['voiceid' => $voice->id, 'type' =>'redpack']);
}
如上可见,将一条包含了语音文件地址的记录id及类型发送到了后端task服务。
后端task服务处理如下:
class DetectVoice extends Action
{
public function run($voiceid, $type = 'redpack')
{
if ($type == 'redpack') {
$voice = Voices::findOne($voiceid);
$url = $voice->voice;
$saveName = '/runtime/redpack-'.$voiceid.'.silk';
$convertName = '/runtime/redpack-'.$voiceid.'.wav';
}
$this->saveToLocalByRemoteVoiceUrlAndLocalFileName($url, $saveName);
$cfg = [
'appKey' => 'xxx',
'appSecret' => 'xxx',
'appId' => 'xxx',
];
$util = new BaiduVoiceUtil($cfg);
$code = exec("bash /www/silk-v3-decoder/converter.sh {$saveName} wav");
if ($code == 0) {
$result = $util->asr($convertName);
if ($result['err_no'] == 0) {
$voicesResult = json_encode($result['result'], JSON_UNESCAPED_UNICODE);
$voice->result = $voicesResult;
$voice->save();
@unlink($saveName);
@unlink($convertName);
}
}
}
...
}
task服务的处理逻辑也很清晰:接收需要识别的voiceid,查找记录,把语音文件下到本地某个tmp目录,调用shell转换格式,将转换后的格式调用baidu的语音接口进行识别,再将结果入库。
voice表结构如下:
如此,便完成了语音识别功能。
红包分配
应用场景:创建红包时
打开红包一般有两种分配方法,一种是使用创建时便分配好每一份的份额。一种是打开时再动态分配,这里采取的是第一种。
具体讨论可在知乎:https://www.zhihu.com/question/22625187 找到。
说实话,看完这个答案还是学到了一些东西的,如微信红包的架构实现,分配写法等等。
因为我们的应用没有微信的量级,自然不需要考虑太多(负载,并发等),产品的要求也只是说金额这方面要实现类微信红包的分配方法即可。因此,考虑到扩展及性能以及时间,分配写法我直接采用了 陈鹏 的答案里的写法,不过是变成了PHP的版本。并且搭配了redis 作为红包份额的存储及可能的并发问题处理方案。
先上代码(redpack/create):
$redpack = $this->getCreatedRedPackByBody();
// ... 业务逻辑代码略
// 设置随机红包份额
$this->setRedPackOpenOdds($redpack);
protected function setRedPackOpenOdds($rp)
{
$remainNum = $rp->num;
$remainMoney = $rp->fee;
$key = 'redpack:'.$rp->id;
$redis = yii::$app->redis;
while (!empty($remainNum)) {
$money = $this->getRandomMoney($remainNum, $remainMoney);
$redis->executeCommand('RPUSH', [$key, $money]);
}
$redis->executeCommand('expire', [$key, 259200]);
}
protected function getRandomMoney(&$remainNum, &$remainMoney)
{
if ($remainNum == 1) {
$remainNum--;
return $remainMoney;
}
$randomNum = StringUtil::getRandom(6, 1);
$seed = $randomNum / 1000000;
$min = 1;
$max = $remainMoney / $remainNum * 2;
$money = $seed * $max;
$money = $money <= $min ? $min : ceil($money);
$remainNum--;
$remainMoney -= $money;
return $money;
}
这部分代码逻辑也相对简单,主要就是:
将当前金额和份数传入函数( getRandomMoney),在计算出当次的随机金额后,将该金额写入redis的一个list (key=redpack:id),然后将总金额和总份数减去,一直减完为止。
有几点值得注意的地方:
1.原答案里的随机数生成法使用了 java.math.BigDecimal. 可php没有对应的函数,自带的随机数也不好用。这里用的自己写的随机数生成方法 (获取6位的随机数字,然后除以它们的位数,就得到类似于 0.608948的随机数) 2.每个红包的份额设置了一天的过期时间,这是为了实现红包过期的功能。
redis里的结果(单位为分):
10元分配15个
100元分配7个:
50元分配25个:
可以看到基本实现了随机分配,也兼顾了手气最佳的要求。
使用也简单,打开红包获取份额的时候,使用这个list左边一个个出栈就行了。
红包地图
应用场景:查看周围发布的红包
这个实现的关键之处就是周边的坐标算法。首先,前提条件是创建红包时要获取到经纬度坐标,这个交由前端实现,我们只记录即可。
然后在调用这个接口时,把用户当前的经纬度传过来。根据这个经纬度计算出周边范围,然后查找表中在这个周边范围的记录即可。
代码如下:
/**
*
* @param double $lng 经度
* @param double $lat 纬度
* @param integer $radius 范围
* @return array
*/
public function run($lng, $lat, $radius = 500)
{
$coordinates = $this->getAroundByCoordinates($lng, $lat, $radius);
$field = 'id,lat,lng';
$data = (new Query())
->select($field)
->from('{{app_redpack}}')
->where(sprintf("`lat` BETWEEN %f AND %f AND `lng` BETWEEN %f AND %f AND `ishandle` = 1 AND `isexpire` = 0", $coordinates[0], $coordinates[2], $coordinates[1], $coordinates[3]))
->all();
return ResponseUtil::getOutputArrayByCodeAndData(Api::SUCCESS, $data);
}
/**
* 地球的圆周是24901英里。
* 24,901/360度 = 69.17 英里 / 度
* @param double $longitude 经度
* @param double $latitude 纬度
* @param integer $raidus 范围。单位米。
* @return array
*/
public function getAroundByCoordinates($longitude, $latitude, $raidus)
{
(double) $degree = (24901 * 1609) / 360.0;
(double) $dpmLat = 1 / $degree;
(double) $radiusLat = $dpmLat * $raidus;
(double) $minLat = $latitude - $radiusLat;
(double) $maxLat = $latitude + $radiusLat;
(double) $mpdLng = $degree * cos($latitude * (pi() / 180));
(double) $dpmLng = 1 / $mpdLng;
(double) $radiusLng = $dpmLng * $raidus;
(double) $minLng = $longitude - $radiusLng;
(double) $maxLng = $longitude + $radiusLng;
return [$minLat, $minLng, $maxLat, $maxLng];
}
关键就是getAroundByCoordinates 这个算法,它根据输入的经纬度及范围大小,计算出左上,左下,右上,右下四个角的坐标,在地图上标出来的话就是 一个长方形的范围。
有兴趣的可以根据 http://lbs.qq.com/tool/getpoint/ 这个工具,随意点取一个坐标,根据以上的方法算出四个角,看看是不是刚好是$raidus指定的范围。
需要说明的是这个方法不是我写的,但是我实在不记得出处在哪了。我只是记得把java的实现方法改成了php。对原作者说声抱歉
-
微信小程序退款功能
2019-08-12 23:31:14下面是我封装的关于微信小程序退款功能,自己在线上...对于此项功能,我建了一个退款记录表,如图所示:此表用于记录退款记录【可根据实际业务逻辑进行修改】 3.以下功能仅实现退款操作,实际业务逻辑,可根据返...下面是我封装的关于微信小程序退款功能,自己在线上项目中是可以实现功能的,所以分享给大家。
注意以下几点:1.我使用的框架偏原生,所以里面关于mysql的部分写法都是偏原生的,不必在意;
2.对于此项功能,我建了一个退款记录表,如图所示:此表用于记录退款记录【可根据实际业务逻辑进行修改】
3.以下功能仅实现退款操作,实际业务逻辑,可根据返回值进行再次进行具体业务逻辑。
/*************************************** **************************************** ***微信小程序退款*********************** **************************************** ****************************************/ /** * 退款 * * 传参: * @param outTradeNo stirng 商户退款单号 * @param totalFee int 订单金额[单位分] * @param refundFee int 退款金额[单位分] * @param refund_desc string 退款原因 * @param openid string 用户openid * @param appid string 微信小程序appid * @param mch_id string 微信商户号 * @param tableName string 数据表名称 * * 注意事项: * 1.交易时间超过一年的订单无法提交退款 * 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 * 【特别注意】*****一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号***** * 3.请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次 * 4.每个支付订单的部分退款次数不能超过50次 */ function refund($outTradeNo,$totalFee,$refundFee,$refund_desc,$openid,$appid,$mch_id,$key,$tableName){ //查询是否有此商户订单号退款失败的记录;如果有,继续使用已有记录中的商户退款单号来进行再次退款;没有,则生成一个新的商户退款单号 $mysql = new Mysql(); $row = $mysql->fetchRow("select * from {$tableName} where openid='{$openid}' and out_trade_no='{$outTradeNo}' order by createTime desc "); unset($mysql); if($row['orderStatus']==3 && $row['cashStatus']==3 && $row['result_code']==2){//表示此商户订单号最近一次业务为退款失败,继续使用之前的商户退款单号 $outRefundNo = $row['outRefundNo']; }else{//表示此商户订单号最近一次业务成功,生成一个新的商户退款单号 $outRefundNo = "tk".date("YmdHis").time();//商户退款单号 } $parma = array( 'appid'=>$appid,//小程序ID 'mch_id'=>$mch_id,//商户号 'nonce_str'=> $this->getNonceStr(),//随机字符串 'out_refund_no'=> $outRefundNo,//商户退款单号 'out_trade_no'=> $outTradeNo,//商户订单号 'total_fee'=> $totalFee,//订单金额[单位分] 'refund_fee'=> $refundFee,//退款金额[单位分] 'refund_desc'=>$refund_desc,//退款原因 ); $parma['sign'] = $this->makeSign($parma,$key); $data = [ 'openid'=>$openid, 'outRefundNo'=>$outRefundNo, 'out_trade_no'=>$outTradeNo, 'refund_desc'=>$refund_desc, 'total_fee'=>$totalFee, 'refund_fee'=>$refundFee, 'createTime'=>time(), 'createIp'=>get_client_ip() ]; $mysql = new Mysql(); $res = $mysql->insert($data,$tableName);//退款记录 if($res){ unset($mysql); $xmldata = $this->arrToXml($parma); $result =$this->curl_post_ssl('https://api.mch.weixin.qq.com/secapi/pay/refund',$xmldata); return $result; }else{ unset($mysql); jReturn(ErrorCode::INSERT_FAIL, '由于系统原因,退款失败'); } } /** * 随机字符串 * @param int $length * @return string */ function getNonceStr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * 签名 * @param $data * @return string */ function makeSign($data,$key) { // 关联排序 ksort($data); // 字典排序 $str = http_build_query($data); // 添加商户密钥 $str .= '&key=' . $key; // 清理空格 $str = urldecode($str); $str = md5($str); // 转换大写 $result = strtoupper($str); return $result; } /** * 数组转XML * @param $data * @return string */ function arrToXml($data) { $xml = "<xml>"; // 遍历组合 foreach ($data as $k => $v) { $xml .= '<' . $k . '>' . $v . '</' . $k . '>'; } $xml .= '</xml>'; return $xml; } /** * [curl_post_ssl 发送curl_post数据] * @param [type] $url [发送地址] * @param [type] $xmldata [发送文件格式] * @param [type] $second [设置执行最长秒数] * @param [type] $aHeader [设置头部] * @return [type] [description] */ function curl_post_ssl($url, $xmldata, $second = 30, $aHeader = array()) { $isdir = $_SERVER['DOCUMENT_ROOT'] . "/oio/global/config/cert/oio/";//证书位置;绝对路径 $ch = curl_init();//初始化curl curl_setopt($ch, CURLOPT_TIMEOUT, $second);//设置执行最长秒数 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 终止从服务端进行验证 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);// curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型 curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置 curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型 curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置 curl_setopt($ch, CURLOPT_CAINFO, 'PEM'); curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem'); if (count($aHeader) >= 1) { curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//设置头部 } curl_setopt($ch, CURLOPT_POST, 1);//post提交方式 curl_setopt($ch, CURLOPT_POSTFIELDS, $xmldata);//全部数据使用HTTP协议中的"POST"操作来发送 $data = curl_exec($ch);//执行回话 if ($data) { curl_close($ch); return $this->xmlToArray($data); } else { $error = curl_errno($ch); echo "call faild, errorCode:$error\n"; curl_close($ch); return false; } }
最后希望大家多多给我点赞,谢谢啦!
-
深入浅出matplotlib(79):在tkinter应用程序里嵌入matplotlib绘图
2021-02-23 17:25:50由于matplotlib绘图的功能非常强大,如果可以嵌入到别的应用程序框架里,这时开发各种各样的应用程序就非常方便了,让应用程序绘图的功能更快速地实现,满足客户的要求。matplotlib支持以下框架: Embedding in GTK...由于matplotlib绘图的功能非常强大,如果可以嵌入到别的应用程序框架里,这时开发各种各样的应用程序就非常方便了,让应用程序绘图的功能更快速地实现,满足客户的要求。matplotlib支持以下框架:
Embedding in GTK3
Embedding in wx #2
Matplotlib With Glade 3
Embedding in Qt
Embedding in Tk
在这里实现一个例子,演示怎么嵌入到Tk的应用程序界面里。结果如下图:
当点击上面按钮时,就会调用matplotlib来绘图:
这是非常强大的功能,对于开发可视化的应用来说,就是小菜一碟。这么强大的功能,可以参考下面的例子代码:
#深入浅出matplotlib-蔡军生(qq:9073204) #https://mysoft.blog.csdn.net/ #2020-02-23 from tkinter import * from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk) # 在tkinter窗口显示matplotlib绘图 def plot(): # 画布 fig = Figure(figsize = (5, 5), dpi = 100) # 平方的数据 y = [i**2 for i in range(101)] # 添加子图 plot1 = fig.add_subplot(111) # 显示曲线 plot1.plot(y) # 创建Tkinter的画布包含Matplotlib figure canvas = FigureCanvasTkAgg(fig, master = window) canvas.draw() # 把画布放到窗口 canvas.get_tk_widget().pack() # 创建Matplotlib工具条 toolbar = NavigationToolbar2Tk(canvas, window) toolbar.update() # 把工具条放到 Tkinter window canvas.get_tk_widget().pack() # Tkinter主要window window = Tk() # 设置标题 window.title('Plotting in Tkinter') # 主窗口的大小 window.geometry("500x500") # 按钮显示曲线绘图 plot_button = Button(master = window, command = plot, height = 2, width = 10, text = "Plot") # 按钮放置 plot_button.pack() # 运行程序主循环 window.mainloop()
-
为应用程序设计一个合适的架构
2021-03-03 00:23:52用例与使用场景功能需求非功能性需要(如性能、安全性、可靠性等质量属性)技术需求部署环境各种限制条件输出设计应生成以下结果:突出架构特点的用例架构的危险区域可用的架构架构测试点步骤图1即是应用架构设计的... -
试编写一个执行以下计算的子程序compute_在 Cloudera Data Flow 上运行你的第一个 Flink 例子...
2020-12-04 20:58:31文档编写目的Cloudera Data Flow(CDF) 作为 Cloudera 一个独立的产品单元,围绕着实时数据采集,实时数据处理和实时数据分析有多个不同的功能模块,如下图所示:图中 4 个功能模块从左到右分别解释如下:Cloudera ... -
用python做一个数据查询软件_使用Python实现NBA球员数据查询小程序功能
2020-12-18 11:37:10以下文章来源于早起Python ,作者投稿君一、前言有时将代码转成带有界面的程序,会极大地方便使用,虽然在网上有很多现成的GUI系统,但是套用别人的代码,心里难免有些尴尬,所以本文将用Python爬虫结合wxpython模块... -
Java实验(五)简单聊天室程序——主要考察图形界面、IO操作和网络编程的结合
2020-05-29 22:58:54本次实验涉及的知识点 1、掌握网络编程的基本概念。 2、掌握java.net包中常用网络编程工具类的功能和使用。...1、在界面布局方面,如图2程序结果显示的中间那块白色的文本域计划用来作为用户输入发送内容的区域,可是 -
绘制搜狐视频功能结构图
2018-09-21 19:59:15昨天发现了一个好用的小程序欸,朋友圈有同学推荐的,叫“小实习”,然后我参加了一个搜狐产品经理实习挑战。第一个任务如题。每个任务有三次提交机会,每次提交完都会有人点评,也是蛮神奇的(不知道是真的有人在... -
完全免费的自动升级程序,短小精悍、功能强大!
2008-10-22 21:35:161. 版本号比较(考虑到可能会有数据方面的升级,因此版本号不从程序自身中取,而是根据需要在配置时设定),同一个软件中允许有多个不同版本的程序或数据。 2. 根据版本号比较结果,从服务器中下载相应程序或数据... -
基于12F629的密码锁(电路图程序仿真打包)
2018-07-03 00:29:525 程序出厂预留有一个【万能密码】(暂不公开,请通过以下技术支持获取),此密码只能使用一次,输入后将开锁一次并永久销毁万能密码功能 6 开锁后将自动于【1分钟】后恢复为锁定状态 操作说明: 1 如何开锁 输入... -
基于Ubuntu的嵌入式开发练习(十)FreeRTOS的移植和设计一个基本的多任务程序
2020-12-01 15:19:49目录一、FreeRTOS的移植二、建立一个基本的多任务程序1、实验要求2、代码设计1、功能代码3、执行效果 一、FreeRTOS的移植 教程(视频):野火 FreeRTOS视频教学 配套书籍《FreeRTOS内核实现与应用开发实战指南》配套... -
从零开始做一个工业级别的实时换脸程序
2019-08-22 14:42:34人像处理技术,是当前大多数人工智能公司很...本场 Chat 带你了解换脸背后的技术,一步步做出一个工业级别的实时换脸程序,主要覆盖以下部分: 使用开源 Dlib 库实现人脸特征点检测及定位 使用 Procrustes Analy... -
怎么做一个简单的图书馆管理系统
2017-04-18 16:29:46(2)需要实现的功能: 1)用户根据口令进入系统 2)图书信息用文件保存,程序运行时从文件读入数据,程序结束前将数据保存在文件中 3)图书信息录入功能和浏览功能 4)排序功能(至少一种排序方式,如出版时间... -
【精】【源码转载+应用说明】小程序搜索功能
2020-04-26 23:47:51最近想要实现小程序的搜索功能,找了很多demo都不理想,不过最后还是在小程序开发社区找到了一个大佬的,可以直接用,大佬的源码这里下载。用到自己的应用里,效果如下图: readme里有引入的说明。另外,自己还有... -
使用Python实现NBA球员数据查询小程序功能
2021-01-21 15:20:53有时将代码转成带有界面的程序,会极大地方便使用,虽然在网上有很多现成的GUI系统,但是套用别人的代码,心里难免有些尴尬,所以本文将用Python爬虫结合wxpython模块构造一个NBA爬虫小软件 本文框架构造将分为二... -
Unity简单实现调用电脑打印机打印图片功能
2020-06-26 22:06:11因为我自己工作方面的原因,在实际的项目中开发过使用调用电脑打印机打印Unity程序中保存的图片的功能。已经很久没有使用过这个功能了,但是今天忽然让测试下这个功能。于是很费劲地翻出以前的项目,实现了这一功能... -
台式机安装SQLSERVER提示:你的电脑上的应用需要使用以下window功能.NET Framework3.5
2021-01-20 15:23:41台式机上安装SQLServer时,提示需要安装.net 3.5,但是,系统提示已经安装了更高版本无法安装,如图: 2. 解决过程 方法一: 1、在控制面板-程序-启用或关闭Windows功能,取消选中.net3.5功能; 2、找到一个win10... -
TVideoGrabber_9.1.1.2官方demo,使用我资源中的lincese可以直接使用,用于图像解码功能强大,可支持各种...
2019-07-04 23:02:16TVideoGrabber是一个用于C#.NET,VB.NET,C ++,Delphi,C ++ Builder和ActiveX兼容应用程序开发的视频捕捉/媒体播放器SDK。 TVideoGrabber功能强大且直观,将帮助您节省时间,金钱和精力,将视频和/或音频功能纳入... -
基于GUI的网络通信程序设计.docx
2020-10-25 16:54:291. 设计一个基于GUI的客户-服务器的通信应用程序,如图1,图2所示。 图1 Socket通信服务器端界面 图2 Socket通信客户端界面 2.图1为Socket通信服务器端界面,点击该界面中的【Start】按钮,启动服务器监 -
基于GUI的网络通信程序设计
2020-10-25 16:33:17@基于GUI的网络通信程序设计 基于GUI的网络通信程序设计 一.实验目的 1.掌握Java中GUI程序的编写,包括...设计一个基于GUI的客户-服务器的通信应用程序,如图1,图2所示。 图1 Socket通信服务器端界面 图2 Socket通 -
google-perftools 源码 (一款针对 C/C++ 程序的性能分析工具)
2011-07-25 22:49:25google-perftools 对一个程序的 CPU 性能剖析包括以下几个步骤。 1. 编译目标程序,加入对 google-perftools 库的依赖。 2. 运行目标程序,并用某种方式启动 / 终止剖析函数并产生剖析结果。 3. 运行剖结果转换工具... -
C语言有趣的小程序
2017-09-21 00:48:00本小程序的各个功能都是通过dos命令来实现的。 运行结果如下图: 该小程序有以下几个功能: 1、启动计算器 2、新建记事本 3、打开画图板 4、定时关机(15s、30s、60s) 5、显示系统时间或修改 6、重启... -
python进行数据查询_使用Python实现NBA球员数据查询小程序功能
2020-12-01 01:50:29以下文章来源于早起Python ,作者投稿君一、前言有时将代码转成带有界面的程序,会极大地方便使用,虽然在网上有很多现成的GUI系统,但是套用别人的代码,心里难免有些尴尬,所以本文将用Python爬虫结合wxpython模块... -
Qt Creator 的安装和hello world 程序+其他程序的编写--不是一般的好
2011-01-28 17:02:08一、Qt Creator 的安装和hello world 程序的编写(原创) 1.首先到Qt 的官方网站上下载Qt Creator,这里我们下载windows 版的。 下载地址:http://qt.nokia.com/downloads 如下图我们下载:Download Qt SDK for ... -
LInux下如何实现图形化添加/删除程序
2009-09-11 12:03:57linux安装过程中,提供了一个可以选择要安装报的界面,使用很方便。 如图1: 但是在安装完成后,这个工具不能用了(确切地说是不...要真正实现system-config-packages的添加/删除程序功能,可以用以下步骤来实现... -
(数据结构)1.实现图的邻接矩阵和邻接表的存储 2.实现图的遍历算法
2019-07-06 11:21:501、编写一个程序graph.cpp,设计带权图的邻接矩阵与邻接表的创建和输出运算,并在此基础上设计一个主程序exp8-1.cpp完成以下功能。 (1)建立如图8.54所示的有向图G的邻接矩阵,并输出之。 (2)建立如图8.54所示的... -
微信小程序Demo:柠檬手帐 - 界面精美的图片编辑应用,支持图片和文字的移动、旋转、缩放、保存编辑状态并...
2019-09-23 18:15:46参加比赛的作品,开发周期一个月,使用了 Wafer2 框架,后台采用腾讯云提供的 Node.js SDK 接入对象存储 API ,前端核心代码实现了类似于图片编辑器的功能,支持图片和文字的移动、旋转、缩放、生成预览图以及编辑...
-
高持续渗透APT攻防培训教材.txt
-
小程序获取用户手机号权限,微信认证
-
学生信息管理系统 教师权限模块 学生权限模块
-
小白学习Java第八天,位运算系统学习
-
软件测试项目实战《全通关》
-
MATLAB给信号添加白噪声
-
双向链表
-
5GG_035_280D_TR8257_SW0394_20200303.rar
-
求阶乘
-
考研答题卡电子版可打印
-
力扣题目:存在三个连续奇数的数组
-
C/C++反汇编解密
-
最新更新区块链CAGI虚拟资产币投资分红理财创投源码+杠杆转账完整源码.zip
-
阿里外包面试题 输出列表[1,3,4,7,2,1,1,5,2]中出现次数最多的值和出现次数(同样多选数值最大的一个)
-
CD 131 找到字符串的最长无重复字串
-
Amoeba 实现 MySQL 高可用、负载均衡和读写分离
-
使用Git进行团队协作
-
用ESP8266+android,制作自己的WIFI小车(Android 软件)wificardemo.zip
-
labview 读取access 表中的数据显示在前面板表格控件实例
-
tesseract-OCR5.0编译好的全部文件.rar