轻松掌握Windows窗体间的数据交互(转载)

轻松掌握Windows窗体间的数据交互
作者:郑佐
日期:2004-04-05
Windows 窗体是用于 Microsoft Windows 应用程序开发的、基于 .NET Framework 的新平台。此框架提供一个有条理的、面向对象的、可扩展的类集,它使您得以开发丰富的 Windows 应用程序。一个Windows窗体就代表了.NET架构里的System.Windows.Forms.Form类的一个实例。
笔者在CSDN技术论坛.NET板块下的C#分类经常看到有人问起如何在两个Form间传递数据,访问修改对方窗体里面的值。对于有经验的程序员来说不是什么高深的东西,而对于初学者来说这些基础的东西往往是一个问题,并且存在这种现象,往往比较复杂的东西他们会,要用什么了就去学什么,实际上并没有真正的去理解掌握它,基础不扎实,所以就有了想通过自己对窗体编程积累的经验来写一些这方面的文章,以供学.NET的朋友参考,也借此机会同各位朋友进行交流,写得不合理的地方请各位朋友提宝贵意见,下面我分了三个部分来讲。
 
一.使用带参数的构造函数
我们要做的准备工作就是新建两个窗体,下面是两个窗体的布局,很简单:
form1form2
说明:Form1为主窗体,包含控件:文本框textBoxFrm1,多选框checkBoxFrm1和按钮buttonEdit;
Form2为子窗体,包含控件:文本框textBoxFrm2,多选框checkBoxFrm2和按钮buttonOKbuttonCancel。
当我们新建一个窗体的时候,设计器会生成默认的构造函数:
public Form2()
{
    InitializeComponent();
}
它不带参数,既然我们要把Form1中的一些数据传到Form2中去,为什么不在Form2的构造函数里做文章呢?
假设我们要实现使Form2中的文本框显示Form1里textBoxFrm1的值,修改子窗体的构造函数:
public Form2(string text)
{
    InitializeComponent();
    this.textBoxFrm2.Text = text;
}
增加Form1中的修改按钮点击事件,处理函数如下:
private void buttonEdit_Click(object sender, System.EventArgs e)
{
    Form2 formChild = new Form2(this.textBoxFrm1.Text);
    formChild.Show();
}
我们把this.textBoxFrm1.Text作为参数传到子窗体构造函数,以非模式方式打开,这样打开的formChild的文本框就显示了”主窗体”文本,是不是很简单,接下来我们传一个boolean数据给子窗体。
Public Form2(string text,bool checkedValue)
{
    InitializeComponent();
    this.textBoxFrm2.Text = text;
    this.checkBoxFrm2.Checked = checkedValue;
}
在主窗体中的修改按钮点击处理,我采用了打开模式窗口的方式,其实在这个例子中看不出有什么分别,
private void buttonEdit_Click(object sender, System.EventArgs e)
{
    Form2 formChild = new Form2(this.textBoxFrm1.Text,this.checkBoxFrm1.Checked);
    formChild.ShowDialog();
}
结果在预料之中,但是这里明显存在不足,在子窗体里的数据修改后不能传给主窗体,也就是说主窗体不受子窗体的影响。而在实际的开发过程中我们经常使用子窗体来修改主窗体里面的数据,那怎么解决呢?
    在.NET中有两种类型,值类型和引用类型。值类型是从ValueType继承而来,而ValueType又是从Object继承;对于引用类型它直接继承Object类型。这下让我们看看怎样通过Form2来修改Form1里的数据。
还是让我们来修改Form2的代码。
Private TextBox textBoxFrm12;
private CheckBox checkBoxFrm12;
public Form2(TextBox heckbo,CheckBox heckbox)
{
    InitializeComponent();
    this.textBoxFrm2.Text = heckbo.Text;
    this.checkBoxFrm2.Checked = heckbox.Checked;
    this.textBoxFrm12 = heckbo;
    this.checkBoxFrm12 = heckbox;
}
现在我们传了两个引用类型的数据:TextBox类型,和CheckBox;另外在Form2中增加了两个类数据成员textBoxFrm12、checkBoxFrm12用来分别保存构造函数传来的变量,不过他们并不属于Form2的Controls容器。修改Form2的确定按钮点击事件函数:
private void buttonOK_Click(object sender, System.EventArgs e)
{
    this.textBoxFrm12.Text = this.textBoxFrm2.Text;
    this.checkBoxFrm12.Checked = this.checkBoxFrm2.Checked;
    this.Close();
}
上面的代码我们通过把textBoxFrm2的Text和checkBoxFrm2.Checked赋给textBoxFrm12和checkBoxFrm12完成了对主窗体中的textBoxFrm1和checkBoxFrm2的修改,因为textBoxFrm1和textBoxFrm12是同一个引用,而checkBoxFrm2和checkBoxFrm12也是。
到这里为止功能是实现了,但是总觉得不是很合理,让两个窗体控件传来传去,现在我举一个恰当一点的例子。
修改了两个窗体:
form11form22
说明:在这个例子中我们的两个窗体都加了一个ListBox用来显示ArrayList中的内容。
主窗体中控件:listBoxFrm1,buttonEdit;
子窗体中控件:listBoxFrm2,textBoxAdd,buttonAdd,buttonEdit,buttonOK。
这次我们用ArrayList来作为传递数据,在Form1中定义类数据成员:
private ArrayList listData1;
在构造函数中增加了对listData1进行内存分配,并生成数据最终绑定到listBoxFrm1,
public Form1()
{
    InitializeComponent();
    this.listData1 = new ArrayList();
    this.listData1.Add("DotNet");
    this.listData1.Add("C#");
    this.listData1.Add("Asp.net");
    this.listData1.Add("WebService");
    this.listData1.Add("XML");
    this.listBoxFrm1.DataSource = this.listData1;
}
另外,对修改按钮点击事件处理函数的修改如下:
private void buttonEdit_Click(object sender, System.EventArgs e)
{
    Form2 formChild = new Form2(this.listData1);
    formChild.ShowDialog();
    this.listBoxFrm1.DataSource = null;
    this.listBoxFrm1.DataSource = this.listData1;
}
相对与主窗体,对子窗体作相应修改,也在Form2中增加了类数据成员:
private ArrayList listData2;
用来保存对主窗体中listData1的引用。
修改构造函数:
public Form2(ArrayList listData)
{
    InitializeComponent();
    this.listData2 = listData;
    foreach(object o in this.listData2)
    {
        this.listBoxFrm2.Items.Add(o);
    }          
}
这里让listData2同listData1指向同一个引用;另外没有对listBoxFrm进行绑定,采用了填充。
好了,下面是对数据操作的时候了。
添加处理函数代码如下:
private void buttonAdd_Click(object sender, System.EventArgs e)
{
    if(this.textBoxAdd.Text.Trim().Length>0)
    {
        this.listData2.Add(this.textBoxAdd.Text.Trim());
        this.listBoxFrm2.Items.Add(this.textBoxAdd.Text.Trim());
    }
    else
        MessageBox.Show("请输入添加的内容!");
}
删除处理代码如下:
private void buttonDel_Click(object sender, System.EventArgs e)
{
    int index = this.listBoxFrm2.SelectedIndex;
    if(index!=-1)
    {
        this.listData2.RemoveAt(index);
        this.listBoxFrm2.Items.RemoveAt(index);
    }
    else
        MessageBox.Show("请选择删除项或者没有可删除的项!");
}
退出Form2子窗体:
private void buttonOK_Click(object sender, System.EventArgs e)
{
    this.Close();
}
编译运行程序,在子窗体中对数据进行修改,关闭后,主窗体就会显示更新后的数据。
这里有一点要提醒一下,比较两个例子,我们都传的是引用类型,一个是String,另一个是ArrayList,为什么string类型不能修改主窗体的数据呢?其实在.Net中对string类型的修改并不是修改原来的值,原来的值没有变化,而是重新生成一个新的字符串,下面是一个很好的说明。
public class ZZConsole
{
    [STAThread]
    static void Main(string[] args)
    {
            string str1 = "abc";
            string str2 = str1;
            str1 = "123";
            Console.WriteLine(str1);
            Console.WriteLine("--------------");
            Console.WriteLine(str2);
            Console.WriteLine("--------------");
            ArrayList al1 = new ArrayList();
            al1.Add("abc");
            ArrayList al2 = al1;
            al2.Add("123");
            foreach(object o in al1)
                Console.WriteLine((string)o);
            Console.WriteLine("--------------");
            foreach(object o in al2)
                Console.WriteLine((string)o);
            Console.ReadLine();
        }
    }
运行一下看看输出结果就明白了,另外对值类型的数据操作要使用ref关键字。
    总结,我们通过带参数的构造函数实现了窗体间的数据交互,代码看上去也比较清楚,在实际开发过程中,可以把DataSet,DataTable,或者是DataView当作参数,当然如果只是想修改一行,可以传个DataRow或者DataRowView。在下我们来看看怎样使用另外两种方法来实现数据的交互。
二.给窗体添加属性或方法
1.使用Form类的Owner属性
获取或设置拥有此窗体的窗体。若要使某窗体归另一个窗体所有,请为其 Owner 属性分配一个对将成为所有者的窗体的引用。当一个窗体归另一窗体所有时,它便随着所有者窗体最小化和关闭。例如,如果 Form2 归窗体 Form1 所有,则关闭或最小化 Form1 时,也会关闭或最小化 Form2。并且附属窗体从不显示在其所有者窗体后面。可以将附属窗体用于查找和替换窗口之类的窗口,当选定所有者窗体时,这些窗口不应消失。若要确定某父窗体拥有的窗体,请使用OwnedForms属性。
上面是SDK帮助文档上讲的,下面我们就来使用它。
首先还是使用第一篇文章中的第二个例子,窗体如下:
form11form22
说明:在这个例子中我们的两个窗体都加了一个ListBox用来显示ArrayList中的内容。
主窗体中控件:listBoxFrm1,buttonEdit;
子窗体中控件:listBoxFrm2,textBoxAdd,buttonAdd,buttonEdit,buttonOK。
主窗体中还是定义类数据成员,
private ArrayList listData1;
在构造函数里实例化它,填充数据,最后绑定到listBoxFrm1。
构造函数如下:
public Form1()
{
    InitializeComponent();
    this.listData1 = new ArrayList();
    this.listData1.Add("DotNet");
    this.listData1.Add("C#");
    this.listData1.Add("Asp.net");
    this.listData1.Add("WebService");
    this.listData1.Add("XML");
    this.listBoxFrm1.DataSource = this.listData1;
}
主窗体的修改按钮处理函数:
private void buttonEdit_Click(object sender, System.EventArgs e)
{
    Form2 formChild = new Form2();
    formChild.Owner = this;
    formChild.ShowDialog();
    this.listBoxFrm1.DataSource = null;
    this.listBoxFrm1.DataSource = this.listData1;
}
我们设置了formChild.Owner为this,这样,子窗体和主窗体就有联系了,
当然我们也可以改成如下:
private void buttonEdit_Click(object sender, System.EventArgs e)
{
    Form2 formChild = new Form2();
    formChild.ShowDialog(this);
    this.listBoxFrm1.DataSource = null;
    this.listBoxFrm1.DataSource = this.listData1;
}
不过这样还不行,目前主窗体的listData1变量外部访问不到,
private ArrayList listData1;
必须修改为public访问修饰符,
public ArrayList listData1;
也可以通过属性(property)来实现,
public ArrayList ListData1
{
    get{return this.listData1;}
}
这里我采用属性,感觉语法更灵活,清楚。
下面是对Form2的修改,
构造函数又恢复原貌了。
public Form2()
{
    InitializeComponent();
}
另外又新增了一个窗体的Load事件,在它的事件处理函数中来获取主窗体中的数据,
private void Form2_Load(object sender, System.EventArgs e)
{
    Form1 pareForm = (Form1)this.Owner;
    this.listData2 = pareForm.ListData1;
    foreach(object o in this.listData2)
        this.listBoxFrm2.Items.Add(o);
}
有人会问,为什么不把上面的代码放到构造函数里面去呢?如下不是更好,
public Form2()
{
    InitializeComponent();
    Form1 pareForm = (Form1)this.Owner;
    this.listData2 = pareForm.ListData1;
    foreach(object o in this.listData2)
        this.listBoxFrm2.Items.Add(o);
}
那我会对你说错了,因为在主窗体修改按钮被点击后,开始执行
Form2 formChild = new Form2();
而在Form2的实例化过程中会在构造函数中执行
Form1 pareForm = (Form1)this.Owner;
而这时的this.Owner是没有值的,为空引用,那么下面的代码肯定也出问题,
this.listData2 = pareForm.ListData1;
foreach(object o in this.listData2)
    this.listBoxFrm2.Items.Add(o);
当整个Form2实例化完成后,才会执行
formChild.Owner = this;
这条代码,所以使用了Form2_Load事件。
那怎样可以不使用Form2_Load事件呢?等下面我们来修改代码实现它。
下面的子窗体代码没有变化,
private void buttonAdd_Click(object sender, System.EventArgs e)
{
    if(this.textBoxAdd.Text.Trim().Length>0)
    {
        this.listData2.Add(this.textBoxAdd.Text.Trim());
        this.listBoxFrm2.Items.Add(this.textBoxAdd.Text.Trim());
    }
    else
        MessageBox.Show("请输入添加的内容!");
}
private void buttonDel_Click(object sender, System.EventArgs e)
{
    int index = this.listBoxFrm2.SelectedIndex;
    if(index!=-1)
    {
        this.listData2.RemoveAt(index);
        this.listBoxFrm2.Items.RemoveAt(index);
    }
    else
        MessageBox.Show("请选择删除项!");
}
private void buttonOK_Click(object sender, System.EventArgs e)
{
    this.Close();
}
好了,结果同第一篇中的一样,子窗体能修改主窗体的值。
 
2.使用自定义属性或方法
下面我们来讲讲怎样使用自定义属性或方法来完成数据修改功能而不使用Form2_Load事件。
主窗体的修改按钮点击处理函数如下:
private void buttonEdit_Click(object sender, System.EventArgs e)
{
    Form2 formChild = new Form2();
    formChild.ListData2 = this.listData1;
    formChild.ShowDialog();
    this.listBoxFrm1.DataSource = null;
    this.listBoxFrm1.DataSource = this.listData1;
}
并且我们去掉了主窗体的ListData1属性,
//public ArrayList ListData1
//{
// get{return this.listData1;}
//}
而在子窗体中加上ListData2属性,
public ArrayList ListData2
{
    set
    {
        this.listData2 = value;
        foreach(object o in this.listData2)
            this.listBoxFrm2.Items.Add(o);
    }
}
也可以把属性改成方法,
public void SetListData(ArrayList listData)
{
    this.listData2 = listData;
    foreach(object o in this.listData2)
        this.listBoxFrm2.Items.Add(o);
}
而在主窗体的修改按钮处理函数中也要相应改动:
formChild.ListData2 = this.listData1;
改为
formChild.SetListData(this.listData1);
    总结,我们通过Form类的Owner属性来建立主从窗体间的桥梁,这个是不是类似于把主窗体作为子窗体的构造函数参数传入实现的功能差不多;另外又采用了属性和方法来完成数据的交互,我觉得这种实现方法很实用,特别是用在不需要实例化类或着已经有了实例的情况下传递数据。下一节我们来讲如何使用静态类来完成数据的交互。
三.使用静态类
    在第一节和第二节中我们使用带参数的构造函数、属性以及方法实现了数据的交互,接下来要讲的是使用静态类来完成窗体间的数据交互。这个也是我们经常要用到的一种数据交互方法。
 
下面是定义的一个类:
using System;
using System.Collections;
namespace ZZ
{
    public class AppDatas
    {
        //静态数据成员
        private static ArrayList listData;
        //静态构造函数
        static AppDatas()
        {
            listData = new ArrayList();
            listData.Add("DotNet");
            listData.Add("C#");
            listData.Add("Asp.net");
            listData.Add("WebService");
            listData.Add("XML");
        }
        //静态属性
        public static ArrayList ListData
        {
            get{return listData;}
        }
        //静态方法
        public static ArrayList GetListData()
        {
            return listData;
        }
    }
}
上面包含了一个静态类成员,listData,一个静态构造函数static AppDatas(),用来初始化listData的数据。还有一个静态属性ListData和一个静态GetListData()方法,他们实现了同样的功能就是返回listData。
另外两个窗体没有改变布局可参看前两篇文章还是如下:
form11form22
由于前面两篇文章已经讲了很多,这个不细说了,下面是完整的代码:
Form1.cs文件
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
 namespace ZZ
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button buttonEdit;
        private System.Windows.Forms.ListBox listBoxFrm1;
        private System.ComponentModel.Container components = null;
        public Form1()
        {
            InitializeComponent();
            this.listBoxFrm1.DataSource = AppDatas.ListData;
           
        }
       
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if(components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }
        #region Windows 窗体设计器生成的代码
        private void InitializeComponent()
        {
            this.buttonEdit = new System.Windows.Forms.Button();
            this.listBoxFrm1 = new System.Windows.Forms.ListBox();
            this.SuspendLayout();
            //
            // buttonEdit
            //
            this.buttonEdit.Location = new System.Drawing.Point(128, 108);
            this.buttonEdit.Name = "buttonEdit";
            this.buttonEdit.TabIndex = 1;
            this.buttonEdit.Text = "修改";
            this.buttonEdit.Click += new System.EventHandler(this.buttonEdit_Click);
            //
            // listBoxFrm1
            //
            this.listBoxFrm1.ItemHeight = 12;
            this.listBoxFrm1.Location = new System.Drawing.Point(12, 8);
            this.listBoxFrm1.Name = "listBoxFrm1";
            this.listBoxFrm1.Size = new System.Drawing.Size(108, 124);
            this.listBoxFrm1.TabIndex = 2;
            //
            // Form1
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
            this.ClientSize = new System.Drawing.Size(208, 141);
            this.Controls.Add(this.listBoxFrm1);
            this.Controls.Add(this.buttonEdit);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
        }
        #endregion
        private void buttonEdit_Click(object sender, System.EventArgs e)
        {
            Form2 formChild = new Form2();
            formChild.ShowDialog();
            this.listBoxFrm1.DataSource = null;
            this.listBoxFrm1.DataSource = AppDatas.ListData;
        }
    }
}
Form2.cs文件
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace ZZ
{
    public class Form2 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button buttonOK;
        private System.ComponentModel.Container components = null;
        private System.Windows.Forms.ListBox listBoxFrm2;
        private System.Windows.Forms.Button buttonAdd;
        private System.Windows.Forms.Button buttonDel;
        private System.Windows.Forms.TextBox textBoxAdd;
        public Form2()
        {
            InitializeComponent();
            foreach(object o in AppDatas.ListData)
                this.listBoxFrm2.Items.Add(o);
        }
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if(components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
        #region Windows 窗体设计器生成的代码
        private void InitializeComponent()
        {
            this.buttonOK = new System.Windows.Forms.Button();
            this.listBoxFrm2 = new System.Windows.Forms.ListBox();
            this.buttonAdd = new System.Windows.Forms.Button();
            this.buttonDel = new System.Windows.Forms.Button();
            this.textBoxAdd = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            //
            // buttonOK
            //
            this.buttonOK.Location = new System.Drawing.Point(188, 108);
            this.buttonOK.Name = "buttonOK";
            this.buttonOK.TabIndex = 0;
            this.buttonOK.Text = "确定";
            this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
            //
            // listBoxFrm2
            //
            this.listBoxFrm2.ItemHeight = 12;
            this.listBoxFrm2.Location = new System.Drawing.Point(8, 8);
            this.listBoxFrm2.Name = "listBoxFrm2";
            this.listBoxFrm2.Size = new System.Drawing.Size(168, 124);
            this.listBoxFrm2.TabIndex = 2;
            //
            // buttonAdd
            //
            this.buttonAdd.Location = new System.Drawing.Point(188, 44);
            this.buttonAdd.Name = "buttonAdd";
            this.buttonAdd.TabIndex = 3;
            this.buttonAdd.Text = "增加";
            this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
            //
            // buttonDel
            //
            this.buttonDel.Location = new System.Drawing.Point(188, 76);
            this.buttonDel.Name = "buttonDel";
            this.buttonDel.TabIndex = 4;
            this.buttonDel.Text = "删除";
            this.buttonDel.Click += new System.EventHandler(this.buttonDel_Click);
            //
            // textBoxAdd
            //
            this.textBoxAdd.Location = new System.Drawing.Point(188, 12);
            this.textBoxAdd.Name = "textBoxAdd";
            this.textBoxAdd.Size = new System.Drawing.Size(76, 21);
            this.textBoxAdd.TabIndex = 5;
            this.textBoxAdd.Text = "";
            //
            // Form2
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
            this.ClientSize = new System.Drawing.Size(272, 141);
            this.Controls.Add(this.textBoxAdd);
            this.Controls.Add(this.buttonDel);
            this.Controls.Add(this.buttonAdd);
            this.Controls.Add(this.listBoxFrm2);
            this.Controls.Add(this.buttonOK);
            this.Name = "Form2";
            this.Text = "Form2";
            this.ResumeLayout(false);
        }
        #endregion
        private void buttonOK_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }
        private void buttonAdd_Click(object sender, System.EventArgs e)
        {
           
            if(this.textBoxAdd.Text.Trim().Length>0)
            {
                 AppDatas.ListData.Add(this.textBoxAdd.Text.Trim());
                this.listBoxFrm2.Items.Add(this.textBoxAdd.Text.Trim());
            }
            else
                MessageBox.Show("请输入添加的内容!");
           
        }
        private void buttonDel_Click(object sender, System.EventArgs e)
        {
            int index = this.listBoxFrm2.SelectedIndex;
            if(index!=-1)
            {
                 AppDatas.ListData.RemoveAt(index);
                this.listBoxFrm2.Items.RemoveAt(index);
               
            }
            else
                MessageBox.Show("请选择删除项!");
        }
    }
}
调试可以看到实现了同样的功能。
    总结,笔者认为使用静态类比较多的地方就是把应用程序的配置文件装载到一个静态类里面,让所有的窗体和其他实例都可以通过静态属性以及静态方法使用这些数据,比如三层结构或多层结构都可以访问它,而不是在多个实例间传来传去。在这里我们讨论的是Windows窗体,其实在两个不同的实例间交互数据,都可以采用文章中的方案实现,除非是这个类特有的属性或着方法。

转载于:https://www.cnblogs.com/wuyu8081/archive/2008/09/30/1302392.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379881.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB安装问题解决方案大集锦

我的安装后的两个问题 第一个:“Microsoft Visual C Runtime LibraryRuntime Error!Program:C:\Matlab7\Rin\Win32\Matlab.exeThis application has requested the runtime to terminate it in an unusual way.Please contact the applications support team for mo…

python免杀技术---shellcode的加载与执行

0x01 生成shellcode 首先通过下列命令生成一个shellcode,使用msfvenom -p选项来指定paylaod,这里选用windows/x64、exec模块接收的参数。使用calc.exe执行弹出计算器的操作。-f选项用来执行生成的shellcdoe的编译语言。 msfvenom -p windows/x64/exec …

成对的歌曲,其总持续时间可被60整除

Problem statement: 问题陈述&#xff1a; In a list of songs, the i-th song has duration of time[i] seconds. Return the number of pairs of songs for which their total duration in seconds is divisible by 60. Formally, we want the number of indices i < j w…

Qt中QTableWidget用法总结

QTableWidget是QT程序中常用的显示数据表格的空间&#xff0c;很类似于VC、C#中的DataGrid。说到QTableWidget&#xff0c;就必须讲一下它跟QTabelView的区别了。QTableWidget是QTableView的子类&#xff0c;主要的区别是QTableView可以使用自定义的数据模型来显示内容(也就是先…

[转]软件架构师书单

"其实中国程序员&#xff0c;现在最需要的是一张安静的书桌。"&#xff0c;的确&#xff0c;中国架构师大多缺乏系统的基础知识&#xff0c;与其自欺欺人的宣扬"读书无用&#xff0c;重在实践变通&#xff0c;修身立命哲学书更重要"&#xff0c;把大好时间…

Java——List集合特有的功能

* List也是一个接口&#xff0c;这说明List不能new&#xff0c;其中它有一个子类ArrayList&#xff0c;所以&#xff0c;就可以父类引用指向子类对象调用* List里面特有的方法&#xff1a;* * void add(int index,E element)在列表的指定位置插入指定元素&#xff08;可选操作&…

python免杀技术---复现+改进----1

0x01 复现 复现文章&#xff1a;https://mp.weixin.qq.com/s?__bizMzI3MzUwMTQwNg&mid2247484733&idx2&sn5b8f439c2998ce089eb44541d2da7a15&chksmeb231%E2%80%A6 首先用cobaltstruke生成一个python的payload脚本 然后复制里面的payload进行Base64编码&…

python掷骰子_用于掷骰子的Python程序(2人骰子游戏)

python掷骰子Here, we will be going to design a very simple and easy game and implement it using abstract data class. The code consists of two different classes (The base of the whole program). The one will be the class for the player and others will be for…

ForeignKey和ManyToManyField的限制关系

authorsmodels.ManyToManyField(Author,limit_choice_to{name__endswith:Smith}这样可以更方便的查询。转载于:https://www.cnblogs.com/chenjianhong/archive/2012/03/22/4145158.html

linux 目录命令_Linux目录命令能力问题和解答

linux 目录命令This section contains Aptitude Questions and Answers on Linux Directory Commands. 本节包含有关Linux目录命令的 Aptitude问答。 1) There are the following statements that are given which of them are correct about Linux commands? In the Linux o…

终于在HP2133上成功安装xp

今天拿到一台HP2133迷你笔记本&#xff0c;原装vista home basic&#xff0c;由于本人是在不喜欢vista&#xff0c;于是决定将使用xp换之。 很久没有研究装系统了&#xff0c;HP2133没有光驱&#xff0c;以前也没啥这方面经验&#xff0c;搞这个玩意安装完软件折腾了大半天&…

Java——GUI(图形用户界面设计)

事件处理&#xff1a;事件&#xff1a;用户的一个操作(例如&#xff1a;点击一下鼠标&#xff0c;或者敲击一下键盘)事件源&#xff1a;被操作的组件(例如&#xff1a;在一个窗体中的一个按钮&#xff0c;那个按钮就属于被操作的组件&#xff0c;按钮就是事件源)监听器&#xf…

python安全攻防---信息收集---IP查询

IP查询是通过当前所获得的URL去查询对应IP地址的过程&#xff0c;可应用Socket库函数中的gethostbyname()获取域名所对用的IP值 程序如下&#xff1a; # -*- coding:utf-8 -*- IP查询import socket ip socket.gethostbyname(www.baidu.com) print(ip)运行结果&#xff1a; …

智能课程表Android版-学年学期星期的实现

上次我们实现了日期和时间的动态显示&#xff0c;这次我们来实现学年&#xff0c;学期&#xff0c;周次的显示&#xff0c;如图: 首先是学年学期的显示&#xff1a; Calendar cCalendar.getInstance(); int yearc.get(Calendar.YEAR); int monthc.get(Calendar.MONTH)1;//Calen…

感染linux脚本程序技术

前言 ---- 本文来源于29A病毒杂志,其上对linux shell病毒技术有了一个综合的阐述,我不想翻译它,我以它的那篇为模板 写了这篇中文的文章,里面的代码我都做了调试. 对于shell编程的程序员来说所谓的shell病毒技术其实根本就是小牛一毛,这点在大家看完本文后就会有所体会 但,简单…

Java——设计模式(简单工厂模式)

* A:简单工厂模式概述* 简单工厂模式又叫静态工厂方法模式&#xff0c;它定义了一个具体的工厂类负责创建一些类的实例* B&#xff1a;优点* 客户端不需要再负责对象的创建&#xff0c;从而明确了各个类的职责* 简单来说&#xff0c;客户端你只需要用就可以了&#xff0c;就…

Java ObjectOutputStream writeFloat()方法与示例

ObjectOutputStream类writeFloat()方法 (ObjectOutputStream Class writeFloat() method) writeFloat() method is available in java.io package. 在java.io包中提供了writeFloat()方法 。 writeFloat() method is used to write the given 4 bytes of a float value. writeFl…

python安全攻防---信息收集---whois查询

whois是用来查询域名的IP以及所有者信息的传输协议。简单地说&#xff0c;whois就是一个数据库&#xff0c;用来查询域名是否以及被注册&#xff0c;以及注册域名的详细信息&#xff08;如域名所有人、域名注册商等&#xff09;。 使用whois查询&#xff0c;首先通过pip安装py…

百度面试题:从输入url到显示网页,后台发生了什么?

参考http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/ http://www.cnblogs.com/wenanry/archive/2010/02/25/1673368.html 原文:http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/ 作为一个软件开发者&#xff0c;你一定会…

VS2005无法启动修复办法

c:\Program Files\Microsoft Visual Studio 8\Common7\IDE>devenv /ResetSkipPkgs 转载于:https://www.cnblogs.com/doc/archive/2008/10/10/1307887.html