Clipper On Line • Ver Tópico - hbqt (again)

hbqt (again)

Projeto Harbour QT - HbQt, HbXBP e HbIDE

Moderador: Moderadores

 

hbqt (again)

Mensagempor MARCELOG » 05 Dez 2011 10:32

Olá pessoal,
continuo estudando a hbqtgui e no processo, criando um pequeno aplicativo.
Optei por criar um menu com base numa tree (qtreewidget).
Conforme a seleção do usuário, a página de uma qstackedwidget relacionada é exibida.
Tudo funcionou sem maiores problemas até a página 6 do qstackedwidget.
Ao criar a página de número 7 num aquivo prg separado e adicioná-lo ao projeto como os demais, tudo ainda funciona certinho.
Todos os procedimentos previsos são normalmente realizados, sem quaisquer erros.
Entretanto, quando fecho o sistema, aparece aquele famigerado aviso de que "O programaX encontrou um problema e precisa ser fechado", indicando o envio de relatório para a Microsoft.
O aviso faz referência ao nome da app e à qtgui4.dll.
Por outro lado, é estranho, já que somente é emitido quando o programa é fechado.
O que poder ser o problema? Tem como solucioná-lo?
Desligar o aviso de erro do Windows para o programa não está entre as opções... (rsrsrsrs)

Obrigado.

MarceloG.
Água mole em pedra dura tanto bate que até espirra!
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

hbqt (again)

Mensagempor Pablo César » 05 Dez 2011 11:01

Pelo que eu sei o QT precisa de algumas bibliotecas que serão utilizadas em run-time. Isto é, precisará sempre carregar com o seu exe os seguintes arquivos: QtCore4.dll, QtGui4.dll, QtNetwork4.dll, QtWebKit4.dll e mingwm10.dll (só não sei se este ultimo destina-se somente ao HMG4. Você também poderá colocar esse aquivos no Windows\system32 (no path do Windows) para não ter que colocar junto em cada sistema. Não estou seguro se são todos esses arquivos, vai colocando um a um a medida que dê erro, pois como eu disse, talvez destina-se para HMG que trabalha com QT agora na versão 4. Maiores informações pode ser obtidas neste tópico: http://hmgforum.com/viewtopic.php?f=24&t=1959&p=16393&hilit=qtgui4.dll#p16393
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar de usuário

Pablo César
Usuário Nível 7

Usuário Nível 7
 
Mensagens: 5312
Data de registro: 31 Mai 2006 10:22
Cidade/Estado: Curitiba - Paraná
Curtiu: 142 vezes
Mens.Curtidas: 152 vezes

hbqt (again)

Mensagempor MARCELOG » 05 Dez 2011 11:17

Olá Pablo,
obrigado por responder.
Mas como eu disse, o sistema funciona normalmente.
Todas as ddl´s necessárias estão presentes.
O único problema é que, ao ser fechado, surge o erro indicado.
Se eu não linkar o último arquivo, tudo funciona legal.
Ao fechado, nesse condição, sem linkar o último aruqivo, o aplicativo não gera qualquer mensagem de erro.

MarceloG

Ps: Vou verificar se houve corrupção de alguma dll.
Água mole em pedra dura tanto bate que até espirra!
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

hbqt (again)

Mensagempor Pablo César » 05 Dez 2011 11:43

Ps: Vou verificar se houve corrupção de alguma dll.
Boa idéia. Mas é esquisito isso.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar de usuário

Pablo César
Usuário Nível 7

Usuário Nível 7
 
Mensagens: 5312
Data de registro: 31 Mai 2006 10:22
Cidade/Estado: Curitiba - Paraná
Curtiu: 142 vezes
Mens.Curtidas: 152 vezes

hbqt (again)

Mensagempor Stanis Luksys » 05 Dez 2011 12:45

Olá,

Normalmente isso ocorre quando você finaliza o programa sem antes matar os objetos.

Para prevenir isso é necessário ter uma função de encerramento EXIT FUNCTION, na qual se atribue valor NIL para os objetos que estão em memória.

Veja também se você está dando um pai para o objeto (sua janela seria o pai), o que pode ser feito através do SetParent().

Se você fizer isso, pode usar um set da Qt, se não me engano, DestroyOnClose, algo assim. Ao fazer isso ele destroi automaticamente todos os filhos da janela quando ela fecha.

Uma outra coisa bastante importante é acabar o programa quando a última janela é fechada, se não me engano é o o QuitOnLastWindowClose.

Não tenho certeza nos nomes dos métodos, e to na correria, não vai dar pra conferir agora, mas da uma olhada no Qt Assistant. A idéia é essa.

Abraços.
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
Avatar de usuário

Stanis Luksys
Colaborador

Colaborador
 
Mensagens: 1329
Data de registro: 18 Jun 2005 03:04
Cidade/Estado: São Paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

hbqt (again)

Mensagempor MARCELOG » 06 Dez 2011 09:27

Olá Stanis,
de novo, obrigado pela atenção.
Mas o negócio é o seguinte:
Estou criando o projeto com base no exemplo do demoqt.prg da pasta tests.
Assim, no prg principal as varáveis para armazenar os objetos foram criadas.
A partir daí, criei a janela principal e o widget central.
Criei um layout vinculado ao widget central e acrescentei à esquerda um treewidget e, à direita, o stackedwidget.
Conforme o treewidget é alterado, a page do stackedwidget é definida.
Para criar as page´s do stackedwidget utilizo uma variável local que recebe de uma função, dentro de uma array, os objetos que a compõem (frames, layouts, labels, lineedits, tables, etc.).
No primeiro argumento, está o widget principal que armazena todos os demais, inclusive os layout´s, e é vinculado ao estackedwidget.
Dessa forma, as variáveis contém os objetos "principais" e os arrays contendo os objetos "secundários" que compõem as pages.
Todos os prg´s que devolvem as arrays têm uma única estrutura, não justificando o aparecimento do erro noticiado em face da inclusão de mais um.
Por outro lado, ao que parece, o erro está acontecendo quando o :exec() é abortado, impedindo a execução das funções posteriores, inclusive a sugerida, que "limpa" a memória.

Exemplo simplificado

no prg principal
...
aPage1:=PAGE1()

stackedwidget:addwidget(aPage[1])
...

function PAGE1()

local a,b,c

a:=qframe()
b:=qvboxlayout(a)
c:=qlabel()

b:addwidget(c)

return {a,b,c}

MarceloG

Ps: os widgets que compõem a stackedwidget, mesmo porque serão adicionados à mesma, s.m.j., não precisam da definição do widget principal, certo?
Água mole em pedra dura tanto bate que até espirra!
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

hbqt (again)

Mensagempor Stanis Luksys » 06 Dez 2011 10:12

Olá,

Avaliando assim rapidamente, acho que o problema pode estar nestas variáveis locais.

Pois veja, você cria o qframe e o qlabel como local, mas não fala quem é o pai deles.

Depois disso o programa sai desta funcao e mata estas variáveis, que eram locais. Os objetos continuam na tela, porém sem referência na memória.

Ao fechar o programa, a própria Qt tenta automaticamente destruir estes objetos, mas como eles não são filhos de ninguém, e não estão diretamente referenciados na memória, da erro.

É só uma hipótese, mude essas vars para pública e coloque um pai para elas através do setparent. Veja se o erro continua.

Se o erro parar, volte essas variáveis para locais, mas arrume um jeito delas serem retornadas para a função que as chamou.

Se sua variável local cria objetos de tela, o normal seria a funcao retornar este objeto, mais ou menos assim:

Function CriaFrame( oObjPai )  //oObjPai é a janela ou widget
   Local frame := QFrame()
   frame:setParent(oObjPai)
   // um monte de sets do frame aqui
Return frame


Você pode retornar vários objetos em um array, e depois trabalhar com eles normalmente também. O importante é que eles continuem na memória quando o program sair da função que os criou.

Abraços.
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
Avatar de usuário

Stanis Luksys
Colaborador

Colaborador
 
Mensagens: 1329
Data de registro: 18 Jun 2005 03:04
Cidade/Estado: São Paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

hbqt (again)

Mensagempor Stanis Luksys » 06 Dez 2011 10:19

Opa,

Eu não tinha prestado atenção, mas você já está retornando os objetos em um array, né? Falha nossa.

Olha, eu não costumo trabalhar desta maneira não. o exemplo do qtdemo é horrível.

Eu crio uma classe para a janela a principal e adiciono objetos nela.

Abraços.

Nota de Moderação:
por Pablo César: Mensagem reditada. Motivo: Item 10 da Regra Geral do Fórum
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
Avatar de usuário

Stanis Luksys
Colaborador

Colaborador
 
Mensagens: 1329
Data de registro: 18 Jun 2005 03:04
Cidade/Estado: São Paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

hbqt (again)

Mensagempor Stanis Luksys » 06 Dez 2011 10:32

Continuando,

Programar com a Qt não fica bom se não for orientado a objetos.

Sempre que uso a Qt, eu utilizo o recurso de herança, para criar os meus objetos. Eu tive que vasculhar muito como os caras lá do harbour fizeram essa gambi com a Qt, mas o resultado é muito bom.

Vou dar um exemplo bem rápido de como eu crio uma Janela principal com um grid dentro:

CREATE CLASS TMainWindow FROM HB_QMainWindow // Crio uma classe que herda tudo da QMainWindow()

    DATA meuGrid  //meu grid passa a ser um obj que nada mais é do que uma propriedde da minha janela

    METHOD create()
    METHOD buildGrid()

ENDCLASS

/* create ***************************/
METHOD TMainWindow:create(  )

   ::setWindowTitle(_APP_NAME)
   ::setWindowIcon( QIcon(_MEU_ICO) )
   ::setMouseTracking(.t.)
   ::setMinimumSize( 500, 530 )
   ::setMaximumSize( 500, 530 )
   ::resize( 500, 530 )
 
   ::buildGrid()  // aqui cria o grid
   
   
RETURN SELF

/* buildGrid ***************************/
METHOD TMainWindow:buildGrid()
   LOCAL x, y, gridItem
   ::grid := QTableWidget( 9, 9, SELF )
   ::grid:move( 25, 50 )
   ::grid:setEditTriggers(0)
   ::grid:setFont( ::fontUser )
   ::grid:verticalHeader:setDefaultSectionSize(50)
   ::grid:verticalHeader:setMinimumSectionSize(50)
   ::grid:horizontalHeader:setDefaultSectionSize(50)
   ::grid:horizontalHeader:setMinimumSectionSize(50)
   ::grid:setHorizontalScrollBarPolicy(1)
   ::grid:setVerticalScrollBarPolicy(1)
   ::grid:verticalHeader:hide()
   ::grid:horizontalHeader:hide()
   ::grid:setMinimumSize(454,454)
   ::grid:setMaximumSize(454,454)
   ::grid:setFrameStyle(QFrame_NoFrame)
   ::grid:setStyleSheet("border: 2px solid #000; gridline-color:#000; color:#4040C0; background-color:white; selection-background-color:#69c; selection-color:#fff")
   ::grid:setSelectionMode(1)
   ::grid:setContextMenuPolicy(3)
   ::grid:setMouseTracking(.t.)
   ::grid:setIconSize(qsize(44,44))
RETURN NIL


Bom, qual a vantagem de trabalhar assim com a herança?

É o seguinte, além de eu ter todos os métodos normais que a janela principal tem por padrão, eu posso adicionar novos métodos, então digamos que estou numa tela de PDV.

Eu posso fazer:

JanelaPDV:setMinimumSize( 500, 530 )     // um metodo padrao da qt
JanelaPDV:adicionarItemNoCupom(params)   // eu que inventei este metodo
JanelaPDV:exibirMsg(params)              // eu que inventei este metodo

Entendeu?
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
Avatar de usuário

Stanis Luksys
Colaborador

Colaborador
 
Mensagens: 1329
Data de registro: 18 Jun 2005 03:04
Cidade/Estado: São Paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

hbqt (again)

Mensagempor MARCELOG » 06 Dez 2011 12:06

Olá pessoal,
obrigado pela dica Stanis, vou estudar os procedimentos.
Todavia, com o método TE (de tentativa e erro), encontrei o problema.
Ao que parece, em algumas situações, o stretch não é corretamente definido para os layouts dentro de layouts, causando o erro.
Assim, desabilitei os mesmos e o programa voltou a funcionar normalmente.
Vou testar outras condições e posto o resultado mais tarde.

Valeu.

MarceloG
Água mole em pedra dura tanto bate que até espirra!
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

hbqt (again)

Mensagempor MARCELOG » 07 Dez 2011 08:50

Olá Stanis,
apesar das alterações efetuadas, o erro persiste.
Deve ser algum bug no objeto que eu pretendo usar, ou seja, o qstackedwidget.
Logo, outra abordagem se faz necessário.
Assim, pretendo deixar um qwidget principal e inserir objetos nele conforme a necessidade, simulando o objeto qstackedwidget.
Para isso preciso saber quais os objetos dentro do mesmo e como "matá-los".
Como você tá fera em hbqt, por acaso sabe como retornar os objetos integrados ao qwidget e matá-los?
O método children e destroy, ao que parece, não foi implementado no qwidget.

Obrigado.

MarceloG
Água mole em pedra dura tanto bate que até espirra!
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

hbqt (again)

Mensagempor Stanis Luksys » 07 Dez 2011 11:18

Olá,

A melhor forma de fazer isso é por herança como eu coloquei mais acima.

Uma vez que eu criei uma classe minha que herda o widget/mainwindow ou seja o que for, eu posso adicionar um método destroy nesta classe e matar todos os objetos filhos apenas fazendo:

Procedure Main()
  // blabla
  janela :=  TMinhaClasse():create()
  janela:show()           // metodo herdado da classe original da qt
  janela:ficarCorDeRosa() // metodo criado
  janela:close()          // metodo herdado
  janela:destroy()        // metodo criado para matar a minha classe
Return

E dentro dela:

METHOD TMinhaClasse:destroy()
   obj1 := NIL
   obj2 := NIL
   obj3 := NIL
RETURN NIL


Eu faço assim.
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
Avatar de usuário

Stanis Luksys
Colaborador

Colaborador
 
Mensagens: 1329
Data de registro: 18 Jun 2005 03:04
Cidade/Estado: São Paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

hbqt (again)

Mensagempor MARCELOG » 10 Dez 2011 12:15

Olá Stanis,
o que eu estou fazendo de errado?
Há compilação mas o arquivo não executa.
Obrigado.

MarceloG

#INCLUDE 'hbclass.ch'
#INCLUDE 'hbqtgui.ch'

//REQUEST HB_CODEPAGE_PT850

//=======================================================================
PROCEDURE MAIN()

LOCAL x, o

x:=QAPPLICATION()

o:=TxMAIN():NEW()

o:SHOW()

x:EXEC()

RETURN

//=======================================================================

CREATE CLASS TxMAIN FROM HB_QMAINWINDOW

       METHOD NEW() // CONSTRUCTOR

ENDCLASS

//=======================================================================

METHOD TxMAIN:NEW()

::SETWINDOWTITLE('cTitulo')
::RESIZE(500,500)

RETURN SELF
Água mole em pedra dura tanto bate que até espirra!
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

hbqt (again)

Mensagempor Stanis Luksys » 11 Dez 2011 10:22

Olá,

Faça o seguinte: altere o nome do seu método new para create, e depois chame assim:

o:=TxMAIN():NEW():CREATE()
o:show()


Deve funcionar.

O método new é padrâo, não deve ser sobreposto por um criado por você, senão ele nâo executa as rotinas necessárias para a criaçâo da janela em sí. Se você cria um método new, deve dentro dele fazer tudo que o new automático faz, ou seja todo o código C. Entendeu?

Abraços.
Stanis Luksys
sites.google.com/hblibs

Apoiar e se utilizar de projetos opensource não é uma questão de boicote, mas sim de liberdade.
Utilize, aprimore e distribua.
Avatar de usuário

Stanis Luksys
Colaborador

Colaborador
 
Mensagens: 1329
Data de registro: 18 Jun 2005 03:04
Cidade/Estado: São Paulo
Curtiu: 0 vez
Mens.Curtidas: 2 vezes

hbqt (again)

Mensagempor MARCELOG » 13 Dez 2011 10:42

Olá Stanis, obrigado!
Entendi os procedimentos.
Nada como um "empurrãozinho" para pegar no tranco.
Vou continuar estudando...

MarceloG
Água mole em pedra dura tanto bate que até espirra!
Avatar de usuário

MARCELOG
Usuário Nível 4

Usuário Nível 4
 
Mensagens: 546
Data de registro: 15 Mar 2005 16:54
Cidade/Estado: Divinópolis/MG
Curtiu: 0 vez
Mens.Curtidas: 6 vezes

Próximo



Retornar para QtContribs - HBQT

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 1 visitante


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro