51CTO技术论坛_中国领先的IT技术社区's Archiver

流氓兔 发表于 2006-8-27 16:02

用PB7.0制作一个电视节目脱机浏览器

随着人们物质文化生活水平的提高和网络的日益普及,上网查电视节目已经不是什么新鲜事了。中央电视台网站(央视国际网站[url=http://www.cctv.com.cn/]http://www.cctv.com.cn[/url])专门制作了电视节目查询网页和查询工具,供我们查询一周内中央和地方电视台各频道的节目,可以按频道、节目名称、起止时间、星期任意查询。尽管如此,上网查电视节目效果并不理想,其主要原因,一是速度慢,二是费用高。一般情况下,很少有人会为查电视节目专门上网。

  如果将电视节目时间表下载到本地硬盘,再做一个浏览器进行脱机浏览,可以大大提高查询速度、降低费用,用起来也更加方便灵活。
  本人用PB7.0制作了一个电视节目脱机浏览器,经过半年多的使用,效果令人满意。下面将实现方法介绍给读者。
  一、数据库与应用程序对象
  [img]http://www.lukin.cn/up_files/image/2006-4-21/60655281.gif[/img]1.建立一个Access 2000数据库tv_acc.mdb(可以是其它数据库),在数据库中建立一个表tv_tab。表结构如图所示。
  在PB中配置ODBC和Profile(命名为tv_acc)。
  2.建立一个PB应用程序对象tv_tab,并对其open事件编写如下代码:
  SQLCA.DBMS="ODBC"
  SQLCA.DbParm="
  ConnectString='DSN=tv_acc;UID=;PWD='" CONNECT USING SQLCA;
  If sqlca.sqlcode  0 Then
  MessageBox ("数据库连接失败", sqlca.sqlerrtext)
  Halt //终止应用程序
  End If
  open(w_tv) //打开电视节目脱机浏览器窗口
  二、窗口设计
  建立如图2所示的窗口对象w_tv。
  标签tab_1有三个标签页tabpage_1、tabpage_2和tabpage_3,每个标签页放一个数据窗口控件,分别命名为dw_1、dw_2和dw_3(图中只标出dw_1)。
  两个下拉列表框ddlb_1和ddlb_2用来选择"星期"和"频道"。
  水平滚动条htb_1、htb_2以及对应的编辑框em_1、em_2用来调整和显示起止时间。
  单行编辑框sle_jm和sle_cnt分别用来指定节目和显示当前记录数。
  静态超级链接shl_1用来连接到中央电视台"节目下载"网页。
  此外,窗口上有cb_1~cb_6六个命令按钮,具体功能将在后面介绍。
  
  


  
[img]http://www.lukin.cn/up_files/image/2006-4-21/60655282.gif[/img]

  (图2)
  

  三、将电视节目导入数据库

  为了便于查询,需要将网上获得的电视节目导入本地数据库。
  电视节目信息的获取方式有以下几种:
  1.利用cctv的电视节目查询系统,提取全部节目信息,保存到本地硬盘。缺点:速度慢、操作麻烦。
  2.在cctv网站订阅节目时间表。特点:纯文本、按时邮寄。
  3.从cctv网站下栽节目时间表,保存到本地硬盘。特点:速度快、操作方便、纯文本、便于导入数据库。网址:[url=http://www.cctv.com.cn/appsvr/showtime/show_time.jsp]http://www.cctv.com.cn/appsvr/showtime/Show_Time.jsp[/url]。本软件采用此种方法。单击窗口的"节目下载"超级链接,可连接到中央电视台网页,进行节目下载。
  单击"导入"按钮,产生clicked事件,通过下面代码将电视节目导入数据库。
  string s_path,s_file,s_line //路径名,文件名,文件行
  string s_rq,s_xq,s_pd,s_sj,s_jm //日期,星期,频道,时间,节目
  integer i_fn,i_code //文件代号,返回码
  getfileopenname("选择目录与文件",s_path,s_file,"TXT","文本文件(*.TXT),*.TXT")
  s_pd=left(s_file,pos(s_file,".")-1) //文件名即为"频道"名
  i_fn = FileOpen(s_path,LineMode!, Read!, LockRead!) //打开文件
  i_code=FileRead(i_fn,s_line) //读一行
  DO while i_code-100 //文件未结束,循环
  IF i_code>0 THEN //不为空行
  IF pos(s_line,"/")>0 and pos(s_line,"星期")>0 THEN //标题行
  s_rq=left(s_line,8) //取得"日期"和"星期"
  s_xq=mid(s_line,pos(s_line,"星期"),6)
  ELSE
  s_sj=left(s_line,5) //取得"时间"和"节目"
  s_jm=mid(s_line,7,80)
  INSERT INTO "tv_tab" ("rq","xq","pd","sj","jm") //插入记录
  VALUES (:s_rq,:s_xq,:s_pd,:s_sj,:s_jm );
  END IF
  END IF
  i_code=FileRead(i_fn,s_line) //读一行
  LOOP
  FileClose(i_fn) //关闭文件
  该程序段用getfileopenname选择节目时间表目录与文件(TXT文件),取出文件名作为"频道"名,打开文件并按行读取,从标题行中取得"日期"和"星期",从其它行中取得"时间"和"节目",形成记录插入数据库的tv_tab表。
  四、任意查询的实现
  电视节目导入数据库的tv_tab表后,可进行任意查询。
  1.建立数据窗口对象d_jmll(节目浏览),网格式,按pd(频道)、rq(日期)、sj(时间)排序。
  2.将第一个标签页上的数据窗口空件dw_1与d_jmll挂接。
  3.相关控件:
  ddlb_1的Items属性为"星期一、星期二、…、星期日"。ddlb_2的Items属性为各频道名称。sle_jm用来输入要查询的电视节目名(可以是一部分)。em_1(起始时间)和em_2(截止时间)的值受控于水平滚动条htb_1和htb_2,用来指定节目的播出时间。
  4."查询"按钮clicked代码
  如果Tab_1.SelectedTab=1(选中第一标签页),则执行下列代码,将满足条件的记录显示在数据窗口控件dw_1中。
  string jstj1 //条件表达式变量
  jstj1="" //形成条件表达式
  IF len(trim(ddlb_1.text))>0 THEN //第一部分(星期)
  jstj1="pos(xq,trim('"+ddlb_1.text+"'))>0"
  END IF
  IF len(trim(ddlb_2.text))>0 THEN //第二部分(频道)
  IF len(jstj1)>0 THEN
  jstj1=jstj1+"and pos(pd,trim('"+ddlb_2.text+"'))>0"
  ELSE
  jstj1="pos(pd,trim('"+ddlb_2.text+"'))>0"
  END IF
  END IF
  IF len(trim(sle_jm.text))>0 THEN //第三部分(节目)
  IF len(jstj1)>0 THEN
  jstj1=jstj1+"and pos(jm,trim('"+sle_jm.text+"'))>0"
  ELSE
  jstj1="pos(jm,trim('"+sle_jm.text+"'))>0"
  END IF
  END IF
  IF len(jstj1)>0 THEN //第四部分(起止时间)
  jstj1=jstj1+"and sj>='"+em_1.text+"' and sj
  ELSE
  jstj1="sj>='"+em_1.text+"' and sj
  END IF tab_1.
  tabpage_1.dw_1.SetFilter(jstj1) //显示查询结果
  tab_1.tabpage_1.dw_1.Filter( )
  五、按时段查询各频道当前正在播出和即将播出的节目
  1.建立数据窗口对象d_sdcx(时段查询),按pd(频道)分组,将细节带向上拖,使细节信息隐蔽起来,而只显示出标题和组信息。分组各项直接用字段名。
  第二、三个标签页上的数据窗口空件dw_2、dw_3均与d_sdcx挂接。
  2.相关的查询项
  ddlb_1(星期)、em_1(时间选择)
  3."查询"按钮clicked代码
  如果Tab_1.SelectedTab不等于1,即选中的是第二、三标签页,则执行下列代码:
  string jstj1,jstj2 //条件表达式变量
  jstj1="xq='"+ddlb_1.text+"' and sj
  jstj2="xq='"+ddlb_1.text+"' and sj>='"+em_1.text+"'" //下个节目检索条件
  tab_1.tabpage_2.dw_2.SetSort("pd A,sj A") //当前节目排序(时间升序)
  tab_1.tabpage_2.dw_2.Sort( )
  tab_1.tabpage_3.dw_3.SetSort("pd A,sj D") //下个节目排序(时间降序)
  tab_1.tabpage_3.dw_3.Sort( )
  tab_1.tabpage_2.dw_2.SetFilter(jstj1) //当前节目检索
  tab_1.tabpage_2.dw_2.Filter( )
  tab_1.tabpage_2.dw_2.GroupCalc() //重新计算、显示组信息
  tab_1.tabpage_3.dw_3.SetFilter(jstj2) //下个节目检索
  tab_1.tabpage_3.dw_3.Filter( )
  tab_1.tabpage_3.dw_3.GroupCalc()
  本段程序在第二标签页上显示出当前正在播出的节目,在第三标签页上显示出即将播出的节目。这是最具特色的部分。
  数据窗口内容按sj(时间)升序排列,并按条件筛选,即可显示出指定时间各频道正在播出的节目,实际上是满足条件各组细节区的最后一条记录内容(节目的播出时间为小于或等于指定时间的最大值)。
  数据窗口内容按sj降序排列,按同一条件筛选,可显示出指定时间各频道即将播出的节目(节目的播出时间为大于或等于指定时间的最小值)。
  六、用滚动条指定时间
  通过移动滚动条的滑块,将当前滑块位置值转换为时间值,存放在编辑框中作为查询条件的一部分。滚动条滑块moved事件的代码为(仅以起始时间滚动条htb_1为例):
  integer hh,mm,n //时、分、分钟数变量
  n=int(14.39*htb_1.position) //滚动条位置值转换为数值(分钟数,100对应1439)
  hh=int(n/60) //转换为时
  mm=mod(n,60) //转换为分
  em_1.text=string(hh)+":"+string(mm) //显示时间
  七、使用
  使用时,首先通过"节目下载"超级链接,到中央电视台网站下在节目时间表,将其保存到本地硬盘的任意一个文件夹并解压缩,单击"清除"按钮,删除tv_tab表中原有记录,单击"导入"按钮,将指定频道的节目信息导入数据库。接下来,选择"任意查询"标签页,可按频道、星期、节目名称和时间范围进行查询,选择"当前节目"或"下个节目"标签页,可查看指定时间正在播出或即将播出的节目。
  "清除"按钮用来删除tv_tab表中全部记录,主要代码为:
  DELETE FROM "tv_tab" ;
  "全部"按钮的作用是清除查询条件并将时间范围设置为最大。以显示全部记录。
  "此时"按钮用来将当前时间设置到em_1,使htb_1滚动条按当前时间定位,并将当前星期作为ddlb_1.text的值。也就是要按现在时刻进行查询。

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.