小弟最近在做客房系统,因为房态图要求的较为复杂一些,用其他的控件不太灵活,于是采用了循环动态创建panel   的方式,然后在panel 上再创建若干需要在不同位置显示相应信息的Label。   完成后测试发现,在循环创建的过程中,速度较慢,尤其当房间数较大时(有可能达到150个),等待时间较长,   在此想请教一下各位,有没有更好的建议和方法。

解决方案 »

  1.   

    你可以把以下的代碼再加線程去處理啊
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        procedure Myonclik(Sender: TObject);
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      i:integer;
    begin
      for i:=1 to 10 do
      begin
        Application.Processmessages();
        with TPanel.Create(self) do
        begin
          Parent:=Self;
          Caption:='Hello,'+IntToStr(i);
          Left:=10;
          Top:=i*(Height+2);
          Name:='L'+ IntToStr(i);
          OnClick:=Myonclik;
        end;
        TPanel(FindComponent('L3')).Caption:='This is Panel 3';
      end;
    end;procedure TForm1.Myonclik(Sender: TObject);
    begin
      showMessage('Button Click!');
    end;end.
      

  2.   

    Panel1.DoubleBuffered := True试试
      

  3.   

                if PanelCount <> 0 then ClearComponent;
                try
                    QueryRoom.First;
                    while not QueryRoom.Eof do
               //此处应替换为从roominfo表中读取房间信息 循环创建
                    begin
                        APanel := TRzPanel.Create(nil);
                        APanel.Parent := ScrollBoxMain;
                        APanel.Tag := QueryRoom.FieldByName('Ro_ID').AsInteger;
                        ARoomName := QueryRoom.FieldByName('Ro_Name').AsString;
                        StrRoomInfo := QueryRoom.FieldByName('Ro_ID').AsString + '|' +
                            QueryRoom.FieldByName('Ro_NO').AsString + '|' +
                            ARoomName + '|' + QueryRoom.FieldByName('Rt_NO').AsString + '|' +
                            QueryRoom.FieldByName('Fi_NO').AsString + '|' +
                            QueryRoom.FieldByName('Ro_Status').AsString;
                        RoomList.Add(StrRoomInfo);
                        if QueryRoom.FieldByName('Rci_NO').AsString = '' then //未入住
                        begin
                            APanel.Caption := ARoomName +
                                #13#10 + '(' + QueryRoom.FieldByName('Rt_Name').AsString + ')';
                      //还要考虑维修房OO VC OC VD OD
                            if QueryRoom.FieldByName('Ro_Status').AsString = 'OO' then
                            begin
                                APanel.Color := clMoneyGreen;
                                RightTopCaption := '维修';
                            end
                            else
                            begin
                                APanel.Color := $00DBD851;
                                if QueryRoom.FieldByName('ResrverFlag').AsString = '0' then
                                begin
                                    RightTopCaption := '空闲';
                                end
                                else
                                begin
                                    RightTopCaption := '预订';
                                end;
                            end;
                        end
                        else
                        begin
                            APanel.Caption := ARoomName +
                                #13#10 + '【' + QueryRoom.FieldByName('Ci_Name').AsString + '】';
                            RightTopCaption := '占';
                            APanel.Color := $00FF9933;
                        end;
                   // APanel.BorderColor := APanel.Color;
                        APanel.BorderColor := clWhite;
                        APanel.BorderWidth := 1;
                        APanel.Height := ARoomHeight;
                        APanel.Width := ARoomWidth;
                        APanel.Font.Color := clWhite;
                        APanel.BorderInner := PanelMain.BorderInner;
                        APanel.BorderOuter := PanelMain.BorderOuter;
                        LastLen := LeftBegin + APanel.Width;
                        if LastLen > ScrollBoxMain.Width then
                        begin
                            LeftBegin := 0;
                            TopBegin := TopBegin + APanel.Height;
                        end;
                        APanel.Top := TopBegin;
                        APanel.Left := LeftBegin;
                        LeftBegin := LeftBegin + APanel.Width;
                        APanel.OnClick := PanelClick;
                        for j := 0 to 4 do
                        begin
                            ALabel := TRzLabel.Create(nil);
                            ALabel.Parent := APanel;
                            ALabel.Transparent := True;
                            ALabel.Tag := j;
                            case j of
                                0: //左上角
                                    begin
                                        ALabel.Left := 10;
                                        ALabel.Top := 10;
                                    end;
                                1: //右上角
                                    begin
                                        ALabel.Left := APanel.Width - 10;
                                        ALabel.Top := 10;
                                        ALabel.Alignment := taRightJustify;
                                    end;
                                2: //左下角
                                    begin
                                        ALabel.Left := 10;
                                        ALabel.Top := APanel.Height - ALabel.Height - 10;
                                        ALabel.Font.Color := clGreen;
                                    end;
                                3: //右下角
                                    begin
                                        ALabel.Left := APanel.Width - 10;
                                        ALabel.Top := APanel.Height - ALabel.Height - 10;
                                        ALabel.Alignment := taRightJustify;
                                        ALabel.Font.Color := clGreen;
                                    end;
                                4: // 房间状态 脏  中底部
                                    begin
                                        ALabel.Left := APanel.Width div 2 - 10;
                                        ALabel.Top := APanel.Height - ALabel.Height - 10;
                                        ALabel.Font.Color := clYellow;
                                    end;
                            end;
                            if j = 1 then
                            begin
                                ALabel.Caption := RightTopCaption;
                            end;
                            if j = 2 then
                            begin
                                case QueryRoom.FieldByName('Ct_Type').AsInteger of
                                    0:
                                        begin
                                            CustomerType := '散';
                                        end;
                                    1:
                                        begin
                                            CustomerType := '团';
                                        end;
                                else
                                    begin
                                        CustomerType := '内';
                                    end;
                                end;
                                ALabel.Caption := CustomerType;
                            end;
                            if j = 4 then
                            begin
                                if (QueryRoom.FieldByName('Ro_Status').AsString = 'VD') or
                                    (QueryRoom.FieldByName('Ro_Status').AsString = 'OD') then
                                begin
                                    ALabel.Caption := '脏';
                                end
                                else
                                begin
                                    ALabel.Caption := '';
                                end;
                            end;
                            ALabel.Visible := True;
                        end;
                        APanel.PopupMenu := PopupMenuPanel;
                        APanel.Visible := True;
                        ProgressForm.ProgBar.StepBy(1);
                        QueryRoom.Next;
                    end;
                finally
                end;
      

  4.   

    如果你的每个Panel上的Label位置、数目都是确定的,可以试试设计期直接创建好这样的模版Form3,运行的时候根据你需要这样的Panel的数目Num进行动态生成。
      LightList: Array of TForm3;  SetLength(LightList, Num);
      for i:=0 to Num-1 do
      begin
        Application.CreateForm(TForm3, LightList[i]);
      end;
      

  5.   

    动态创建200个panel应该不会太费时啊
    或者,先把它们的parent隐藏,200个都创建完了再显示?或者干脆利用一个image画格子代表房间,更灵活
      

  6.   

    楼主要用 scorllbox控件,再把它设为 doublebuffed:=true。
    我是这样做的,效果很好。
      

  7.   

    按楼上的 将doublebuff启用 不过效果不太明显呀 
    还有更好点的方法吗? 
      

  8.   

    还有一个办法,使用自画的stringgrid
      

  9.   

    Stringgrid 局限性太大,很多特定的功能不太好实现
      

  10.   

    要提高效率,封装房间远比单个创建相应“零件”要有效率的多,重用、扩展性能也好很多。简单提供一个思路:
    1.用frame封装房间组成的组件,Panel也好,label也好,共性的东西一起作为父类,规定房间的共同属性,如价格、面积、户型等等。
    2.派生各类个性化房间,设置其个性化属性。
    3.生成房间时,直接以组件的样式生成对应Frame
    当然,依此类推,写一个简单的组件也不是不可以:)
      

  11.   

    建议:
    1、写一个组件。
    2、使用 TPrintPreview;通过Canvas画图。
      

  12.   

    呵呵,这是实践出来的,自然差不了:)零碎组件的创建和封装组件的效率是没有可比性的,用Delphi千万不能纠结在细碎的小组件上,大OOP的思想要贯彻项目始终,需求越复杂,受益就越多