在做针对视频的主观质量测试时,需要让受试者通过测试界面进行观看与打分。因此做了一个简易的测试界面,采集用户的信息和打分情况,并导入SQL数据库,方便进一步的处理。测试流程分为7步,即图中对应的7个序号,本篇博客将对各部分的逻辑和代码进行梳理,整体难度不大,由于时间紧迫很多功能不完善。
总体步骤如下:
- 输入个人信息
- 选取测试视频添加到3中的Listbox中,若不需要随机打乱序列顺序,则跳过步骤3,直接播放
- 对视频信息进行随机打乱,保证实验随机性,并进行播放
- 视频播放完毕,进行主观打分
- 打分完成后,点击”确认打分“保存对应视频信息、打分情况,并自动播放下一个,当视频播放结束时,隐藏”确认打分“按钮。若要修改之前已打过分的视频,双击6中对应的视频,重新打分后点击”确认修改“
- 存储个人信息、视频信息和打分信息
- 导出到数据库或Excel
接下来进行代码分析。
1.个人信息的输入
个人信息部分通过4个Label标签,3个Textbox文本框以及一个确定Button实现,通过管理确定Button的脚本实现个人信息的导入,代码如下
private void button6_Click(object sender, EventArgs e) { dataGridView1.Rows.Add(" ", " ", " ", textBox2.Text, textBox3.Text, textBox4.Text); //添加到6中的dataGridView1,前三列保存视频序号、名称和打分信息,便于数据库读取 label6.Visible = false; //输入信息后,1中所有组件可见性设置为false label7.Visible = false; label8.Visible = false; label9.Visible = false; textBox2.Visible = false; textBox3.Visible = false; textBox4.Visible = false; button6.Visible = false; MessageBox.Show("输入成功!"); }
输入信息后,点击确定按钮后,导入6中的Excel表格。
2.添加并播放
在button1中输入如下代码(
需要改进
)
private void button1_Click(object sender, EventArgs e) { string str = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; listBox1.Items.Clear(); listBox1.Items.Add(@str + "TimeTest\\timetest1\\video_1.mp4"); //添加 listBox1.Items.Add(@str + "TimeTest\\timetest1\\video_2.mp4"); listBox1.Items.Add(@str + "TimeTest\\timetest1\\video_3.mp4"); listBox1.Items.Add(@str + "TimeTest\\timetest1\\video_4.mp4"); // button7.PerformClick(); //随机打乱控制开关 axWindowsMediaPlayer1.Ctlcontrols.play(); button2.PerformClick(); //播放按钮 } private void button2_Click(object sender, EventArgs e) //button2按钮,控制播放 { listBox1.SelectedIndex = 0; //从第一个开始播放 axWindowsMediaPlayer1.URL = listBox1.SelectedItem.ToString(); }
3.Listbox信息的随机打乱
进行随机打乱可以保证测试的随机性。随机打乱按钮的脚本如下
private void button7_Click(object sender, EventArgs e) { List<string> temp1 = new List<string>(); //两个List用作存储,List1进行读取,随机打乱后赋值给List2 List<string> temp2 = new List<string>(); foreach (var item in this.listBox1.Items) { temp1.Add(item.ToString()); } int total = listBox1.Items.Count; //控制打乱的文件数量 int[] hashtable = new int[total]; int[] output = new int[total]; Random random = new Random(); for (int i = 0; i < total; i++) //随机排序 { int num = random.Next(0, total); while (hashtable[num] > 0) { num = random.Next(0, total); } output[i] = num; hashtable[num] = 1; temp2.Add(temp1[num]); } listBox1.Items.Clear(); //清空当前的Listbox foreach (string E in temp2) //将temp2中的数据添加到Listbox中 { listBox1.Items.Add(E); } //MessageBox.Show("序列已打乱!"); }
4.打分控件
打分控件通过radioButton实现,并将所有radioButton放置在groupBox之中,防止用户多选分数造成错误。
每个radioButton的脚本只用于读取用户的信息
代码如下
private void radioButton1_CheckedChanged(object sender, EventArgs e) { if (radioButton1.Checked) { textBox1.Text = radioButton1.Text; } }
如下图所示,分数就添加到了红框之中。
5.保存打分结果
在确定打分情况后,点击“确认打分并播放下一个”可以保存当前视频信息和打分情况,实现如下,
private void button4_Click(object sender, EventArgs e) { if (listBox1.SelectedIndex < listBox1.Items.Count - 1) //当前索引未到最后,则添加打分信息 { dataGridView1.Rows.Add((dataGridView1.Rows.Count - 1), listBox1.Items[listBox1.SelectedIndex].ToString(), textBox1.Text); ++listBox1.SelectedIndex; axWindowsMediaPlayer1.URL = listBox1.Items[listBox1.SelectedIndex].ToString(); } else //否则弹出finish界面 { dataGridView1.Rows.Add((dataGridView1.Rows.Count - 1), listBox1.Items[listBox1.SelectedIndex].ToString(), textBox1.Text); MessageBox.Show("finish!"); } }
此时修改打分按键默认时不显示的。
若要修改之前打分的结果,为数据表添加双击事件,代码如下
private void dataGridView1_MouseDoubleClick(object sender, MouseEventArgs e) { button4.Visible = false; //隐藏“确认打分并播放下一个” button8.Visible = true; //显示“确认修改并返回当前” axWindowsMediaPlayer1.URL=dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value.ToString(); //双击数据表,读取双击的行数,并播放该行索引为[1]的地址 }
其中“确认修改并返回当前”代码如下
private void button8_Click(object sender, EventArgs e) { dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[2].Value = textBox1.Text; //修改数据表中当前行的分数 button4.Visible = true; //显示“确认打分并播放下一个” button8.Visible = false; //隐藏“确认修改并返回当前” listBox1.SelectedIndex = dataGridView1.Rows.Count - 2; //通过当前数据表存储的信息返回之前播放的视频 axWindowsMediaPlayer1.URL = listBox1.Items[listBox1.SelectedIndex].ToString(); }
6.数据表的存储
用dataGridView存储即可,添加几个空列。
7.导出到Excel/数据库
一般分析、处理数据的话,用Excel即可,先给出导出到Excel的方法
private void button5_Click(object sender, EventArgs e) { string fileName = ""; string saveFileName = ""; SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.DefaultExt = "xls"; saveDialog.Filter = "Excel文件|*.xls"; saveDialog.FileName = fileName; saveDialog.ShowDialog(); saveFileName = saveDialog.FileName; if (saveFileName.IndexOf(":") < 0) return; Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); if (xlApp == null) { MessageBox.Show("无法创建Excel对象,您的电脑可能未安装Excel"); return; } Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks; Microsoft.Office.Interop.Excel.Workbook workbook = workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet); Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1 for (int i = 0; i < dataGridView1.ColumnCount; i++) { worksheet.Cells[1, i + 1] = dataGridView1.Columns[i].HeaderText; } for (int r = 0; r < dataGridView1.Rows.Count; r++) { for (int i = 0; i < dataGridView1.ColumnCount; i++) { worksheet.Cells[r + 2, i + 1] = dataGridView1.Rows[r].Cells[i].Value; } System.Windows.Forms.Application.DoEvents(); } worksheet.Columns.EntireColumn.AutoFit(); if (saveFileName != "") { try { workbook.Saved = true; workbook.SaveCopyAs(saveFileName); } catch (Exception ex) { MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message); } } xlApp.Quit(); GC.Collect();//强行销毁 dataGridView1.Rows.Clear(); //恢复初始状态,方便下一位测试者 label6.Visible = true; label7.Visible = true; label8.Visible = true; label9.Visible = true; textBox2.Text = ""; textBox3.Text = ""; textBox4.Text = ""; textBox2.Visible = true; textBox3.Visible = true; textBox4.Visible = true; button6.Visible = true; MessageBox.Show("恭喜,完成测试!"); }