Ivano Postado Dezembro 6, 2006 Denunciar Share Postado Dezembro 6, 2006 Olá amigos,Estou precisando copiar "nós" de uma treeView para outra. Só que tem de ser na mesma posição que estava, porque as arvores são iguais...Alguém sabe me dizer como pegar e passar esse 'caminho'?Desde já agradeço a ajuda dos amigos! ;-) Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Churc Postado Dezembro 6, 2006 Denunciar Share Postado Dezembro 6, 2006 opatipo, salva o conteúdo numa stream e depois você puxa na outra treeview exemplovarss: tmemorystream;begin ss := tmemorystream.create; try treeview1.savetostream(ss); ss.position := 0; treeview2.loadfromstream(ss); finally ss.free; end;abraço Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 6, 2006 Autor Denunciar Share Postado Dezembro 6, 2006 Olá Churc,Não sei se entendi bem, mas assim elas ficarão exatamente iguais, não é?Eu vou precisar jogar apenas um nó de cada vez, de acordo com o que o usuario selecionar...[]´s Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Micheus Postado Dezembro 6, 2006 Denunciar Share Postado Dezembro 6, 2006 Estou precisando copiar "nós" de uma treeView para outra. Só que tem de ser na mesma posição que estava, porque as arvores são iguais...Olá Churc,Não sei se entendi bem, mas assim elas ficarão exatamente iguais, não é?Eu vou precisar jogar apenas um nó de cada vez, de acordo com o que o usuario selecionar...[]´sSe são iguais, mas você quer copiar apenas um nó de cada vez, então você quer fazer como?Supondo:+- Pai 1 | +- Filho 1 | | +- Neto 1 | | | L- Bisneto 1 | | L- Neto 2 | L- Filho 2 +- Pai 2 | +- Filho 1 | L- Neto 1 | +- Filho 2 | | L- Neto 1 | | +- Bisneto 1 | | L- Bisneto 2 +- Pai 3 L- Filho 1 +- Neto 1 L- Neto 21) Estando selecinado Bisneto 1 (Pai 1\Filho 1\Neto 1), você quer copiar para a outra árvore o Bisneto 1 e seus predecessores (Pai 1, Filho 1 e Neto 1)?2) Se estiver selecionado Neto 1 (Pai 2\Filho 2), você quer copiar para a outra árvore o Neto 1 e seus predecessores (Pai 2\Filho 2) apenas, ou também seus sucessores (Bisneto 1 e Bisneto 2)? Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Churc Postado Dezembro 6, 2006 Denunciar Share Postado Dezembro 6, 2006 Só que tem de ser na mesma posição que estava, porque as arvores são iguais...Então, baseado no que você disse achei que seria uma cópia pois como seria colocados nas "mesmas posições", caso o usuário selecionar, baseado no exemplo do Micheus "Bisneto 1" e "Bisneto 2"?responde a pergunta do Micheus que ai fica mais fácil de te ajudar...abs Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 7, 2006 Autor Denunciar Share Postado Dezembro 7, 2006 ok amigos,respondendo as perguntas:1) Sim, é isso mesmo. Exatamente.2) Não isso já não é necessário nesso momento, embora seja interessante eu aprender isso também. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Churc Postado Dezembro 7, 2006 Denunciar Share Postado Dezembro 7, 2006 opaentão, eu fiz de um jeito aqui, não é o melhor jeito mas pelomenos está funcionando auhauhestá meio gambiarra usar StringList, tentei fazer sem usar mastava dando muito trabalho, talvez alguém poste uma rotinamelhor ou voce a melhore... expliquei mais ou menos o queaconteceProcedure CopiaTreeviews(TreeViewA, TreeViewB: TTreeView); var sl: TStringList; Node: TTreeNode; i: Integer; begin //checa se foi passado os treeview if ((TreeViewA = nil) or (TreeViewB = nil)) then Exit; //pega o item selecionado Node := TreeViewA.Selected; //cria uma lista para poder armazenar os items sl := TStringList.Create; //como vai sendo pego debaixo pra cima, então vamos //adicionar o item selecionado... sl.Insert(0, Node.Text); //enquanto houver filiações quanto ao item selecionado... while (Node <> nil) do begin //pega a filiação Node := Node.Parent; //se houver filiação ou a posição for maior ou igual a zero, //no caso 0 é o root ou seja, o primeiro item de tudo, o Pai :P if ((Assigned(Node)) and (Node.Level >= 0)) then //insere no começo da lista, pois como mencionado é pego de baixo //para cima sl.Insert(0, Node.Text); end; //agora vamos adicionar na outra treeview os itens pegos... for i := 0 to sl.Count - 1 do begin //se o i = 0 quer dizer que é o Pai, então colocamos ele //como primeiro de tudo, e não adicionamos filiação, no caso Nil if (i = 0) then Node := TreeViewB.Items.AddChild(nil, sl[i]) else //se for maior que 0 quer dizer que é filiação, e é passado a //filiação anterior que é pega em Node := Treeview2.Items.AddChild(... Node := TreeViewB.Items.AddChild(Node, sl[i]) end; sl.Free; end;para usar exemplo,CopiaTreeviews(TreeView1, TreeView2);desse jeito não pega multselect... vai precisar?abraço Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 7, 2006 Autor Denunciar Share Postado Dezembro 7, 2006 testei ele aqui, ficou bem legal! :))Não precisa multselect não, a unica coisa que vai ter de mudar é queele gerar um "nível 0" a cada vez que chamamos a função.Acho que se comparar antes se o Pai já existe na árvore, daí ele encontra e já copia lá, né?Cara muito obrigado pela ajuda, você é muito gente boa! :-) Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 8, 2006 Autor Denunciar Share Postado Dezembro 8, 2006 Pessoal, pensei que iria ser fácil, mas está cada vez mais confuso :(Como eu faço para verificar se o nó Pai correspondente existe na outra árvore e, se não, criar a estrutura e copiar o nó, ou se não copiar apenas o nó pra lá?Detalhe: Eu posso ter o pai A com os filhos A1 e A3 a esquerda e já ter o Pai "A" correspondente na árvore com o nó filho A2. Então eu querer copiar o A2 para a direita.O que eu não estou conseguindo fazer: 1-Verificar se já existe esse nó, pegando um "endereço". Assim:Pega o nome do Pai: "A"2-Compara na "arvore 2" se existe um pai "A" (isso eu acho que sabendo pegar esse endereço fica mais fácil, usando um count e comparando TODOS, porque o nó não terá a mesma posição "count" )3- Se for criar a estrutura, verificar se já existe o avô e etc...O problema maior é pegar esse endereço :(, estou ficando loco com isso!Isso é difícil assim mesmo de fazer ou eu é que estou marcando touca? Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Micheus Postado Dezembro 8, 2006 Denunciar Share Postado Dezembro 8, 2006 Pessoal, pensei que iria ser fácil, mas está cada vez mais confuso :(Como eu faço para verificar se o nó Pai correspondente existe na outra árvore e, se não, criar a estrutura e copiar o nó, ou se não copiar apenas o nó pra lá?Detalhe: Eu posso ter o pai A com os filhos A1 e A3 a esquerda e já ter o Pai "A" correspondente na árvore com o nó filho A2. Então eu querer copiar o A2 para a direita.Ivano, agora você diz que se um nó existe na lista da direita, mas não existe na da esquerda, você quer copiar ele para a lista da esquerda??? :blink: Afinal, você quer mover apenas da esquerda para a direita ou em qualquer direção?Acho que resolvida esta questão, a resolução das outras dúvidas fica mais fácil.1-Verificar se já existe esse nó, pegando um "endereço". Assim:Pega o nome do Pai: "A"É esse endereço vai ter que ser o texto do item, mas respeitando a hierarquia, pelo que você já citou antes, porque eventualmente se você tiver itens com mesmo nome em posições diferentes da árvore, vai virar uma bagunça. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 11, 2006 Autor Denunciar Share Postado Dezembro 11, 2006 Amigos,Eu sei está confuso, mas também porque realmente é complicada a coisa.Estou tentando fazer agora, de forma mais simples.O que preciso nesse momento agora é saber como avançar um nó.Tentei encontrar isso nos axemplos acima mas não encontrei.Fazer algo do tipo: arvore2.nó.next;Com isso já consigo fazer funcionar o FOR que preciso e a coisa anda.Isso porque entendo que assim "Selected" irá passar para o próximo, correto?Obrigado pela atenção e paciência de vocês. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Churc Postado Dezembro 11, 2006 Denunciar Share Postado Dezembro 11, 2006 o que você quer fazer?não deu pra entender sua explicação...você quer que se na árvore que vai receber os itens selecionados, já tiver uma filiaçãoigual então adicionar a ela ao invés de criar uma uma nova? Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 11, 2006 Autor Denunciar Share Postado Dezembro 11, 2006 É assim:Posteriormente eu irei carregar informações de minha base de dados em duas árvores.Daí alguns pontos deverão aparecer a direita e outros a esquerda, dependendo do "status" dela na tabela. Então alguns pontos "filhos" irão aparecer só na arvore da direita ou só na arvore da esquerda.Até aí tudo bem.Depois o usuario irá clicar em um item da esquerda e enviar para a direita. Nesse momento eu vou mudar o status desse item na tabela, o que é tranquilo.Mas eu tenho de verificar se o pai dele já está na arvore de destino. Se já estiver eu coloco ele lá. Se não estiver tenho de colocar antes o pai dele, ok?Até qui eu consegui comparar se o nó já existe atraves do parâmetro:NodeOri := PInteger( arvore.Selected.Data )^;Mas eu tenho de clicar no item na arvore de destino, se não ele não encontra!Meu "For" não funciona! olha como esle está nesse momento:--------------------var nodeori, nodedes: integer; //TTreeNode; i: Integer; nodesel: TTreeNode;begin NodeOri := PInteger( arvore.Selected.Data )^;//arvore.Selected; for i := 0 to arvore2.Items.Count-1 do Nodedes:= PInteger( arvore2.Selected.Data )^; if NodeOri = Nodedes then begin showmessage('Achei! É: '+IntToStr(Nodedes)); i:=i+1; end;-------------------Se eu conseguir correr todos os níveis procurando o pai, e se não encontrar procurar pelo avô, daí eu coloco eles lá. Se eu não fizer isso terei de carregar o Select várias vezes e vai ficar muito pesado :(Consegui explicar o problema agora? Entenderem o que eu quero fazer e para que? Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 11, 2006 Autor Denunciar Share Postado Dezembro 11, 2006 Correção! Agora funcionou, estou trabalhando nele, olha só! :)---------------------------------var nodeori, nodedes: integer; i: Integer; nodesel: TTreeNode;begin NodeOri := PInteger( arvore.Selected.Data )^; for i := 0 to arvore2.Items.Count-1 do begin form1.Caption:=arvore2.Items.text; Nodedes:= PInteger( arvore2.items.Data )^; if NodeOri = Nodedes then begin showmessage('Achei! É: '+IntToStr(Nodedes)); end; end; Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Churc Postado Dezembro 11, 2006 Denunciar Share Postado Dezembro 11, 2006 opabaseado naquela primeira rotina que te passei, e baseado no quevocê disse depois veja se é isso que precisaProcedure CopiaTreeviews(TreeViewA, TreeViewB: TTreeView); var sl: TStringList; Node: TTreeNode; i: Integer; begin //checa se foi passado os treeview if ((TreeViewA = nil) or (TreeViewB = nil)) then Exit; //pega o item selecionado Node := TreeViewA.Selected; //cria uma lista para poder armazenar os items sl := TStringList.Create; //como vai sendo pego debaixo pra cima, então vamos //adicionar o item selecionado... sl.Insert(0, Node.Text); //enquanto houver filiações quanto ao item selecionado... while (Node <> nil) do begin //pega a filiação Node := Node.Parent; //se houver filiação ou a posição for maior ou igual a zero, //no caso 0 é o root ou seja, o primeiro item de tudo, o Pai :P if ((Assigned(Node)) and (Node.Level >= 0)) then //insere no começo da lista, pois como mencionado é pego de baixo //para cima sl.Insert(0, Node.Text); end; //agora vamos adicionar na outra treeview os itens pegos... for i := 0 to sl.Count - 1 do begin //se o i = 0 quer dizer que é o Pai if (i = 0) then begin //não adicionamos parentesco Node := nil; //Se houver items na arvore2 então procuramos por parentesco if (TreeViewB.Items.Count > 0) then begin //começamos pelo primeiro item Node := TreeViewB.Items.Item[0]; //procuramos pela árvore inteira while Node <> nil do //opa achamos ele :P if (AnsiCompareText(sl[i], Node.Text) = 0) then Break else Node := Node.GetNext; end; //não achamos parentesco, então adicionamos como uma nova familia... if (Node = nil) then Node := TreeViewB.Items.AddChildFirst(nil, sl[i]) else //se achou a familia, então apenas adiciona o item selecionado a ela begin TreeViewB.Items.AddChild(Node, sl[sl.Count - 1]); Break; end; end else //se for maior que 0 quer dizer que é filiação, e é passado a //filiação anterior que é pega em Node := Treeview2.Items.AddChild(... Node := TreeViewB.Items.AddChild(Node, sl[i]) end; sl.Free; end;Fiz a busca baseada no nome do item, então se houver itens com o mesmo nomevai dar conflito, então altere a busca de Nome pra ponteiros como você fez na suarotina acimaabraços Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Ivano Postado Dezembro 14, 2006 Autor Denunciar Share Postado Dezembro 14, 2006 Depois de muita ajuda de vocês consegui fazer funcionar do jeito que eu precisava. Deu trabalho mas ficou bom!Voi postar aqui como ficou para o caso de algém poder precisar.A procedure está funcionando do jeito que está. A única coisa é que se ela não encontrar o pai, ela irá incluir apenas o primeiro "ancestral", e não todos até o nó que foi procurado em primeiro lugar.Muito obrigado a todos! :)-------------------------------------------------------------var NodeOriAux, NodePaiOri, NodeOri, NodeDes: integer; //TTreeNode; qtdNodes, c, i, ii: Integer; nodesel: TTreeNode; texto: string; achou: boolean;begin NodePaiOri := PInteger(arvore.Selected.Parent.Data)^; NodeOri := PInteger(arvore.Selected.Data)^; texto:=arvore.Selected.text; c:=0; i:=0; for c := 0 to arvore.Items.Count-1 do begin //vai procurar o pai depois se não encontrar o filho, seria bom calcular o nº de antepassados... for i := 0 to arvore2.Items.Count-1 do begin // Vai procurar em todos os nós da 2º arvore, se preciso NodeDes:= PInteger( arvore2.items.Data )^; //Node de destino na 2º arvore if NodePaiOri = NodeDes then begin //O pai do Node de origem é = ao de destino? showmessage('Achei! o Pai dele é: '+IntToStr(NodeDes)); //Se sim, é nele que vai o node de Origem! New(rg); rg^:= NodeOri; arvore2.Items.AddChildObject(arvore2.items, texto, rg); Exit; end; end; arvore.TopItem; //Se não sair vai p o topo da árvore 1 ii:=0; for ii := 0 to arvore.Items.Count-1 do begin //Vai procurar o cara Pai arvore para achar o Avô NodeOriAux := PInteger(arvore.items[ii].Data )^; if (NodeOriAux = NodePaiOri) then begin //Se achou... //qtdNodes:=qtdNodes+1; NodeOri := PInteger(arvore.items[ii].Data)^; //o node de origem fica sendo o Pai texto:=arvore.items[ii].text; //atualiza o texto. NodePaiOri := PInteger(arvore.items[ii].Parent.Data)^; //o avô vira Pai... break; end; end; end;end; Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Micheus Postado Dezembro 14, 2006 Denunciar Share Postado Dezembro 14, 2006 Ivano, apenas umas dicas...seria bom calcular o nº de antepassados...no objeto TreeNode há a propriedade Level que determina o nível na hierarquia aonde o nó se encontra - veja se era a isso que você se referia.New(rg);aparentemente rg é um ponteiro para inteiro, certo?NodePaiOri := PInteger(arvore.Selected.Parent.Data)^;Observe que a propriedade Data é do tipo pointer. Se você deseja armazenar uma estrutura simples, como um integer nesta propriedade. Não se dê a o trabalho de alocar memória para isto, desde que a informação caiba no SizeOf(Pointer) -> 4 bytes. As coisas podem, então, serem mais simples:- Para escrever o conteúdo faça apenas: Arvore.Selected.Parent.Data := Pointer(NodePaiOri);- Para ler: NodePaiOri := LongInt(Arvore.Selected.Parent.Data); Citar Link para o comentário Compartilhar em outros sites More sharing options...
Pergunta
Ivano
Olá amigos,
Estou precisando copiar "nós" de uma treeView para outra. Só que tem de ser na mesma posição que estava, porque as arvores são iguais...
Alguém sabe me dizer como pegar e passar esse 'caminho'?
Desde já agradeço a ajuda dos amigos! ;-)
Link para o comentário
Compartilhar em outros sites
16 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.