zoukankan      html  css  js  c++  java
  • MyKTV项目,走起!

    MyKTV项目,走起!

    第一部分:这个项目对于新手来说有一点难度,但是当你理清类之间的关系和怎样去实现功能后就会感觉轻松很多。

    话不多说,先上类图:

    接着是数据库表间关系:

     

    本项目要实现以下功能:

    1. 明星点歌
    2. 拼音点歌
    3. 类型选择
    4. 金榜排行
    5. 字数点歌

    一共五大块,那么明星点歌下还有一个播放的功能。

    在主页面有一个正在播放和下一首的提示功能。

    这是ktv主页面:

    在下边还有重唱切歌已点服务退出功能

    相信大家都去过KTV,所以这些功能就不说了,比我都清楚!

    这里我把播放控件放在了主页面,位置随意,放在哪都行,也可以单独开一个窗体进行播放。

    点击明星点歌进入到明星点歌页面:

     

    组合,女歌手和男歌手都放在listView中,这里要注意的是在这一个窗体中一共有三个listView,先在窗体中隐藏后两个,

    那么点击第一个进入到第二个时要把第一个listView隐藏。

    隐藏listView只需把它的Visible属性设置成false就ok了:

    1             lvCountry.Visible = false;
    2             lvSinger.Visible = false;

    第二个listView就是供用户一个更精确的选择歌曲或歌手了:

    第三个listView就是显示歌手对应的图片:

    这个图片要从数据库中取,不能写死,还有很多功能,像金榜排行,都不能写死。

    再次点击就进入播放列表:

    刷新歌曲列表代码:

     1         /// <summary>
     2         /// 刷新歌曲列表
     3         /// </summary>
     4         private void RefreshSongList()
     5         {
     6             lvSongList.Items.Clear();  // 清空原列表
     7             int i = 0;
     8             while (PlayList.SongList[i] != null)
     9             {
    10                 ListViewItem item = new ListViewItem();
    11                 item.Text = PlayList.SongList[i].SongName;                
    12                 item.Tag = i;
    13                 string playState = PlayList.SongList[i].PlayState== SongPlayState.unplayed?"未播放":"已播放";
    14                 item.SubItems.Add(playState);
    15                 lvSongList.Items.Add(item);
    16                 i++;
    17             }
    18         }

    明星点歌代码:

      1      string singertype = "组合";
      2         int singertypid = 0;
      3 
      4      /// <summary>
      5         /// 第一层listView
      6         /// </summary>
      7         public void LoadSingerArea() 
      8         {
      9             if (lvType.SelectedItems[0]!=null)
     10             {
     11                 lvType.Visible = false;
     12                 lvCountry.Visible = true;
     13                 lvCountry.Location = lvType.Location;
     14                 lvCountry.Dock = DockStyle.Fill;
     15                 this.singertype = Convert.ToString(lvType.SelectedItems[0].Text);
     16             }                    
     17             string sql = "select singertype_id,singertype_name from singer_type";
     18             SqlCommand cmd = new SqlCommand(sql,db.Connection );
     19             try
     20             {
     21                 db.OpenConnection();
     22                 SqlDataReader dr = cmd.ExecuteReader();
     23                 lvCountry.Items.Clear();
     24                 if (dr.HasRows)
     25                 {
     26                     int index = 0;
     27                     while (dr.Read())
     28                     {
     29                         ListViewItem lvitem = new ListViewItem();
     30                         int typeid = Convert.ToInt32(dr["singertype_id"]);
     31                         string typename = Convert.ToString(dr["singertype_name"]);
     32                         lvitem.Text = typename;
     33                         lvitem.Tag = typeid;
     34                         lvitem.ImageIndex = index;
     35                         lvCountry.Items.Add(lvitem);
     36                         index++;
     37                     }
     38                 }
     39                 dr.Close();
     40             }
     41             catch (Exception ex)
     42             {
     43 
     44                 MessageBox.Show(ex.Message);
     45             }
     46             finally
     47             {
     48                 db.CloseConnection();
     49             }
     50         }
     51         /// <summary>
     52         /// 第二层listView
     53         /// </summary>
     54         public void LoadSingerName() 
     55         {
     56             if (lvCountry.SelectedItems[0]!=null)
     57             {
     58                 //隐藏歌手地区,显示歌手的姓名
     59                 lvCountry.Visible = false;
     60                 lvSinger.Visible = true;
     61                 lvSinger.Location = lvCountry.Location;                               
     62                 singertypid = Convert.ToInt32(lvCountry.SelectedItems[0].Tag);
     63                 StringBuilder sql = new StringBuilder();
     64                 string result = singertype;
     65                 if (result!="组合")
     66                 {
     67                     result = singertype == "女歌手" ? "" : "";
     68                 }
     69                 sql.AppendFormat("select singe_id,singer_name,singer_photo_url from Singer_info where singertype_id={0}and singer_gemder='{1}'",singertypid,result);
     70                 SqlCommand cmd = new SqlCommand(sql.ToString(), db.Connection);
     71                 try
     72                 {                    
     73                     db.OpenConnection();
     74                     SqlDataReader dr = cmd.ExecuteReader();
     75                     int imageIndex = 0; //代表歌手头像的索引
     76                     imageList1.Images.Clear();
     77                     lvSinger.Items.Clear();
     78                     if (dr.HasRows)
     79                     {
     80                         while (dr.Read())
     81                         {
     82                              string photoURL = KTVUtil.singerPhotoPath + "\" + Convert.ToString(dr["singer_photo_url"]);
     83                             imageList1.Images.Add(Image.FromFile(photoURL));
     84                             ListViewItem item = new ListViewItem();
     85                             item.Text = Convert.ToString(dr["singer_name"]);
     86                             item.Tag = Convert.ToString(dr["singer_id"]);
     87                             item.ImageIndex = imageIndex;
     88                             lvSinger.Items.Add(item);
     89                             imageIndex++;
     90                         }
     91                     }
     92                     dr.Close();
     93                 }
     94                 catch (Exception ex)
     95                 {
     96                     MessageBox.Show(ex.Message);
     97                 }
     98                 finally 
     99                 {
    100                     db.CloseConnection();
    101                 }
    102             }
    103         }
    104 
    105         private void tsplMenu_Click(object sender, EventArgs e)
    106         {
    107             MainForm mf = new MainForm();
    108             mf.Show();
    109             this.Close();
    110 
    111         }
    112         /// <summary>
    113         /// 第三层listView
    114         /// </summary>
    115         public void SongList()
    116         {
    117             StringBuilder sb = new StringBuilder();
    118             sb.AppendFormat("select song_id,song_name, singer_name='{0}',song_url  from SongInfo,Singer_Info where singer_id={1}",
    119                 lvSinger.SelectedItems[0].Text, Convert.ToInt32(lvSinger.SelectedItems[0].Tag));
    120 
    121             SongListForm songList = new SongListForm();
    122             songList.Sql = sb.ToString();
    123             songList.Show();
    124             this.Close();
    125         }

    之后一定要在listView的Click事件中调用方法:

     1      private void lvType_Click(object sender, EventArgs e)
     2         {
     3             LoadSingerArea();
     4         }
     5 
     6         private void lvSinger_Click(object sender, EventArgs e)
     7         {
     8             SongList();
     9         }
    10 
    11         private void lvCountry_Click(object sender, EventArgs e)
    12         {
    13             LoadSingerName();
    14         }

    播放过程:

    当选中某首歌曲后,点击一下,那么就会将各个列的值拼接成一个Song对象,

    1 Song song=new Song();
    2 song.songName="";
    3 song.songUrl="地址";

    歌曲列表中数据来源于数据库!所以我们要将喜欢的歌曲添加到数据库中!

    当我们点击已点的时候就会循环遍历数组,然后每遍历一项,就会创建一个 ListViewItem对象。

    刚才忘了说了,每个页面下面的菜单我用的是ToolStrip控件。

    接下来是拼音点歌

    拼音点歌相对来说就简单多了,就是一个模糊查询,页面如下:

    拼音点歌部分代码:

     1         // 查询歌曲显示在窗体中
     2         private void btnSearch_Click(object sender, EventArgs e)
     3         {                       
     4             DBHelper dbHelper = new DBHelper();
     5             DataSet dataSet = new DataSet();
     6             StringBuilder sb = new StringBuilder();
     7             sb.Append("select song_id,song_name,singer_name,song_url  from song_info inner join singer_info on singer_info.singer_id=song_info.singer_id ");
     8             sb.AppendFormat("where song_name like '%{0}%' or song_ab like '{0}'",this.txtSongName.Text);
     9 
    10             Console.WriteLine(sb.ToString());
    11 
    12             SqlDataAdapter adapter = new SqlDataAdapter(sb.ToString(), dbHelper.Connection);
    13 
    14              // 清空当前列表
    15             if (dataSet.Tables["songList"] != null)
    16             {
    17                 dataSet.Tables["songList"].Clear();
    18             }
    19 
    20             adapter.Fill(dataSet, "songList");
    21             this.dgvSong.DataSource = dataSet.Tables["songList"];            
    22         }

    类型点歌:

    这个和酷狗里的如下页面功能类似:

    点击某一个项进入到相应的歌曲页面,部分代码如下:

     1  // 窗体加载时,显示歌曲类别
     2         private void OrderBySongTypeForm_Load(object sender, EventArgs e)
     3         {
     4             // 读取歌曲类别
     5             DBHelper dbHelper = new DBHelper();
     6             string sql = "select * from song_type";
     7             try
     8             {
     9                 // 查询数据库
    10                 SqlCommand command = new SqlCommand(sql, dbHelper.Connection);
    11                 dbHelper.OpenConnection();
    12                 SqlDataReader reader = command.ExecuteReader();
    13 
    14                 // 循环将类别读取出来添加到ListView中
    15                 this.lvSongType.Items.Clear();
    16                 int i = 0;
    17                 while (reader.Read())
    18                 {
    19                     ListViewItem item = new ListViewItem();
    20                     item.Text = Convert.ToString(reader["songtype_name"]);
    21                     item.Tag = Convert.ToInt32(reader["songtype_id"]);
    22                     item.ImageIndex = i;
    23                     this.lvSongType.Items.Add(item);
    24                     i++;
    25                 }
    26                 reader.Close();
    27             }
    28             catch (Exception ex)
    29             {
    30                 Console.WriteLine(ex.Message);
    31                 MessageBox.Show("系统错误,请联系服务人员!");
    32 
    33             }
    34             finally
    35             {
    36                 dbHelper.CloseConnection();
    37             }
    38         }

    金榜排行和字数点歌大家可以尝试着写一下,都不难!字数点歌这里要注意一下:

    上边的那12个Label不是拖12个Label控件,而是利用二重数组进行控制Label的:

     1         for (int i = 1; i <= 5; i++)//行数
     2              {
     3                 for (int j = 1; j <= 5; j++)
     4                 {
     5                     Label label = new Label();
     6                     label.Text = i+"-"+j;
     7                     //自身大小(重点)
     8                     label.Size = new Size(80, 50);
     9                     //背景颜色
    10                     label.BackColor = Color.Yellow;
    11                     //相对于窗体0,0点的位置
    12                     label.Location = new Point(20+100*j, 20+80*i);
    13                     //文本居中
    14                     label.TextAlign = ContentAlignment.MiddleCenter;
    15                     //字体大小
    16                     label.Font=new Font("Bradley Hand ITC",20);17                     //触发Click事件
    18                     label.Click += label_Click;
    19                    20                     //让Label对象归属于当前窗体
    21                     this.Controls.Add(label);
    22                 }
    23             }
    24 
    25         }
    26 
    27         void label_MouseMove(object sender, MouseEventArgs e)
    28         {
    29             this.Text = e.X + "" + e.Y;
    30         }
    31 
    32         void label_Click(object sender, EventArgs e)
    33         {
    34            35             Label label = (Label)sender;36             MessageBox.Show(label.Text);37             
    38 
    39         }
    40 
    41         private void Form1_MouseMove(object sender, MouseEventArgs e)
    42         {
    43             this.Text = e.X + "" + e.Y;
    44         }

    要记住:每一个控件都是一个类。

    第二部分:

    部分关键代码如下:

    1.重唱:

    1 // 重新播放当前歌曲
    2         private void tsbtnAgain_Click(object sender, EventArgs e)
    3         {
    4             PlayList.PlayAgain();
    5         }

    就是调用PlayList中的PlayAgain()方法。PlayList类我会在下面给出。

    2.切歌:

     1         // 切歌
     2         private void tsbtnCut_Click(object sender, EventArgs e)
     3         {
     4             if (MessageBox.Show("确定要切歌吗?", "操作提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
     5             {
     6                 int songId = -1;  // 切歌的编号
     7                 if (this.lvSongList.SelectedItems.Count > 0)
     8                 {
     9                     songId = Convert.ToInt32(this.lvSongList.SelectedItems[0].Tag);
    10                 }
    11                 PlayList.CutSong(songId);
    12                 this.RefreshSongList();
    13             }
    14         }

    3.播放:

     1         private Song song;//当前播放的歌曲
     2         //播放歌曲
     3         private void PlaySong()
     4         {
     5             this.song = PlayList.GetPlaySong();//获取当前播放的歌曲
     6             if (song != null)
     7             {
     8                 this.song.SetSongPlayed();//已播放
     9                 //D:song恋爱新手.mp3
    10                 Player1.URL = KTVUtil.songPath + "\" + this.song.SongURL;//得到当前播放歌曲的路径
    11                 txtNext.Text = this.song.SongName;
    12             }
    13         }

    4.PlayList类:

      1 /// <summary>
      2     /// 播放列表管理
      3     /// </summary>
      4     class PlayList
      5     {
      6         private static Song[] songList = new Song[50]; // 歌曲播放列表数组
      7         private static int songIndex = 0;  // 当前播放的歌曲在数组中的索引      
      8 
      9         /// <summary>
     10         /// 播放列表数组
     11         /// </summary>
     12         public static Song[] SongList
     13         {
     14           get { return PlayList.songList; }          
     15         }
     16 
     17         /// <summary>
     18         /// 当前播放歌曲的索引
     19         /// </summary>
     20         public static int SongIndex
     21         {
     22             get { return PlayList.songIndex; }
     23         }
     24 
     25         /// <summary>
     26         /// 当前播放的歌曲名称
     27         /// </summary>
     28         /// <returns>歌曲名称</returns>
     29         public static string PlayingSongName()
     30         { 
     31             string songName = ""; // 歌曲名称
     32             if (SongList[SongIndex] != null)
     33             {
     34                 songName = SongList[SongIndex].SongName;
     35             }
     36 
     37             return songName;
     38         }
     39 
     40         /// <summary>
     41         /// 获取当前播放的歌曲
     42         /// </summary>
     43         /// <returns>当前要播放的歌曲</returns>
     44         public static Song GetPlayingSong()
     45         {
     46             if (SongList[songIndex] != null)
     47             {
     48                 return SongList[songIndex];
     49             }
     50             else
     51             {
     52                 return null;
     53             }
     54         }
     55 
     56         /// <summary>
     57         /// 下一首要播放的歌曲名称
     58         /// </summary>
     59         /// <returns>歌曲名称</returns>
     60         public static string NextSongName()
     61         {
     62             string songName = ""; // 歌曲名称
     63             if (SongList[SongIndex+1] != null)
     64             {
     65                 songName = SongList[SongIndex+1].SongName;
     66             }
     67 
     68             return songName;
     69         }
     70         
     71         /// <summary>
     72         /// 点播一首歌曲
     73         /// </summary>
     74         /// <param name="song">新点播的歌曲</param>
     75         public static bool AddSong(Song song)
     76         {
     77             bool success = false;
     78             for (int i = 0; i < SongList.Length; i++)
     79             {
     80                 if (SongList[i] == null)
     81                 {
     82                     SongList[i] = song;
     83                     Console.WriteLine(song.SongName);
     84                     success = true;
     85                     break;
     86                 }
     87             }
     88 
     89             return success;
     90         }
     91 
     92         /// <summary>
     93         /// 切歌
     94         /// </summary>
     95         /// <param name="index">要切歌曲的编号,如果是切当前播放的歌曲传入-1</param>
     96         public static void CutSong(int index)
     97         {
     98             int i;  // 循环变量,代表切歌的位置
     99             if (index == -1)
    100             {
    101                 i = SongIndex;                
    102             }
    103             else
    104             { 
    105                 i = index; // 从切歌的位置开始,将歌曲逐个向前移一个位置
    106             }
    107 
    108             SongList[i].SetSongCut();
    109             while (SongList[i] != null)
    110             {
    111                 SongList[i] = SongList[i + 1];   
    112                 i++;
    113 
    114                 // 如果到达数组最后一个元素,就将最后一个元素指向空
    115                 if (i == SongList.Length)
    116                 {
    117                     SongList[i] = null;
    118                 }
    119             }
    120         }
    121 
    122         /// <summary>
    123         /// 重放当前歌曲
    124         /// </summary>
    125         public static void PlayAgain()
    126         {
    127             if (SongList[songIndex] != null)
    128             {
    129                 SongList[songIndex].SetPlayAgain();
    130             }
    131         }
    132 
    133         /// <summary>
    134         /// 播放下一首
    135         /// </summary>
    136         public static void MoveOn()
    137         {
    138             if (SongList[songIndex] != null && SongList[songIndex].PlayState == SongPlayState.again)
    139             {
    140                 SongList[songIndex].SetSongPlayed();
    141             }
    142             else
    143             {
    144                 songIndex++;
    145             }            
    146         }       
    147     }

    5.Song类:

     1     enum SongPlayState
     2     { 
     3         unplayed,played,again,cut  
     4     }
     5     
     6     
     7     /// <summary>
     8     /// 歌曲类
     9     /// </summary>
    10     class Song
    11     {        
    12         /// <summary>
    13         /// 歌曲名称
    14         /// </summary>
    15         public string SongName
    16         {
    17             get { return songName; }
    18             set { songName = value; }
    19         }
    20 
    21         /// <summary>
    22         /// 歌曲存放路径
    23         /// </summary>
    24         public string SongURL
    25         {
    26             get { return songURL; }
    27             set { songURL = value; }
    28         }
    29 
    30         /// <summary>
    31         /// 歌曲播放状态
    32         /// </summary>
    33         internal SongPlayState PlayState
    34         {
    35             get { return playState; }
    36             set { playState = value; }
    37         }
    38         
    39         private string songName;
    40         private string songURL;
    41         private SongPlayState playState = SongPlayState.unplayed;  // 歌曲播放状态
    42 
    43         
    44         /// <summary>
    45         /// 将歌曲状态改为已播放
    46         /// </summary>
    47         public void SetSongPlayed()
    48         {
    49             this.playState = SongPlayState.played;
    50         }
    51 
    52         /// <summary>
    53         /// 将歌曲状态改为再拨放一次
    54         /// </summary>
    55         public void SetPlayAgain()
    56         {
    57             this.playState = SongPlayState.again;
    58         }
    59 
    60         /// <summary>
    61         /// 将歌曲状态改为切歌
    62         /// </summary>
    63         public void SetSongCut()
    64         {
    65             this.playState = SongPlayState.cut;
    66         }
    67     }

    6.KTVUtil类:

    这里主要存的就是路径

    1         public static string singerPhotoPath = "";  // 歌手照片路径
    2         public static string songPath = "";         // 歌曲路径

    7.SongList类:

     1 public enum PalySongState 
     2     {
     3        //未播放 , 播放, 重播,切歌
     4        unplayed,played,again,cut
     5     }
     6     /// <summary>
     7     /// 歌曲播放类
     8     /// </summary>
     9      public class SongList
    10     {
    11          //歌曲名称
    12         private string SongName;
    13          //歌曲路径
    14         private string SongUl;
    15          //歌曲状态
    16         private string SongState;
    17 
    18         public string SongState1
    19         {
    20             get { return SongState; }
    21             set { SongState = value; }
    22         }
    23 
    24         public string SongUl1
    25         {
    26             get { return SongUl; }
    27             set { SongUl = value; }
    28         }
    29 
    30         public string SongName1
    31         {
    32             get { return SongName; }
    33             set { SongName = value; }
    34         }
    35 
    36          //把当前的播放状态设置为未播放状态
    37        private  PalySongState playSong = PalySongState.unplayed;
    38 
    39         public  PalySongState PlaySong
    40         {
    41             get { return playSong; }
    42             set { playSong = value; }
    43         }
    44          /// <summary>
    45          /// 将未播放状态改为播放状态
    46          /// </summary>
    47         public void PalyState() 
    48         {
    49             this.PlaySong = PalySongState.played;
    50         }
    51          /// <summary>
    52          /// 将歌曲重新播放
    53          /// </summary>
    54         public void AgainState() 
    55         {
    56             this.PlaySong = PalySongState.again;
    57         }
    58          /// <summary>
    59          /// 切歌状态
    60          /// </summary>
    61         public void CutState() 
    62         {
    63             this.PlaySong = PalySongState.cut;
    64         }
    65     }

    那么以上就是本次的KTV项目了,这个只是前台,那么大家也可以写一个后台进行管理和维护前台,通过数据库就可以

    把前台和后台连在一起。

  • 相关阅读:
    PHP版本VC6与VC9/VC11/VC14、Thread Safe与None-Thread Safe等的区别
    Django 开发------django-crontab实现服务端的定时任务
    django HTML 数据处理
    HTML 罗盘式时钟
    Tcpdump 常用命令、参数记录
    jquery 实现 <imput>标签 密码框显示/隐藏密码功能
    Django 实现分页功能(django 2.2.7 python 3.7.5 )
    bootstrap 4 学习笔记
    IIS属性解析
    IIS站点权限设置
  • 原文地址:https://www.cnblogs.com/wcf6676/p/4690722.html
Copyright © 2011-2022 走看看