Qt-jambi-interest Archive, November 2007
Issue with font size in Widget
Message 1 in thread
Hello,
First of all thanks to TT to have permitted Java prog the use of the
wonderfull QT :)
Here is my issue. I have mixed some QT Jambi with swing (a former app
I "translate" from swing to QTJambi screen by screen).
From a swing JFrame, when I click on a swing button, my app open a QTJambi
QDialog.
All work correctly.
Then I close the QDialog (using the classical :
lscreen.exit.clicked.connect(this, "close()");) and then if I try to open a
new time my QDialog all is correct except the font size of all Widget who are
biggest !
Here is the way I launch my QDialog :
if ("GO".equals(e.getActionCommand())) {
String[] args = {"",""};
QApplication.initialize(args);
MyScreen diagAnniv = new MyScreen();
diagAnniv.show();
QApplication.exec();
}
This is not a big problem because I can use a screen with big size fonts, but
I would like to understand.
Thanks for your help.
Message 2 in thread
paul wrote:
> Hello,
>
> First of all thanks to TT to have permitted Java prog the use of the
> wonderfull QT :)
>
> Here is my issue. I have mixed some QT Jambi with swing (a former app
> I "translate" from swing to QTJambi screen by screen).
> From a swing JFrame, when I click on a swing button, my app open a QTJambi
> QDialog.
> All work correctly.
> Then I close the QDialog (using the classical :
> lscreen.exit.clicked.connect(this, "close()");) and then if I try to open a
> new time my QDialog all is correct except the font size of all Widget who are
> biggest !
>
> Here is the way I launch my QDialog :
>
> if ("GO".equals(e.getActionCommand())) {
> String[] args = {"",""};
> QApplication.initialize(args);
> MyScreen diagAnniv = new MyScreen();
> diagAnniv.show();
> QApplication.exec();
> }
>
> This is not a big problem because I can use a screen with big size fonts, but
> I would like to understand.
> Thanks for your help.
Hi Paul,
There are a few things I immediatly see in your code that are wrong.
First is that QApplication can and should only be initialized once.
This should give an exception, but because you call exec() on it it will
reset the internal pointer. We will probably add an runtime exception to
catch this kind of error for a future release. My guess is that the font
issue is a side effect of that you're doing an illegal thing with
QApplication, namely initializing twice.
The second problem is that Swing you are executing this code on the
Swing Event thread, which is not favorable... On Linux and Windows, I
believe this will "just work", but there might be side effects... There
is also the case that you cannot do exec(), e.g. process Qt events, as
this blocks the swing event loop. On Mac OS X, you will get an error if
QApplication is not started on the first thread.
Another issue might be intended, but still, QDialogs should be shown
using exec() rather than show(). The reason for this is that exec() will
properly nest the event loop and preserve modality. If you don't use
modal dialogs, it is less of a problem.
The last problem here is that Qt applications automatically shut down
when you close the last window. This is a convenience feature, which you
in your scenario don't want. You want QApplication.exec to run "forever"
and never exit. To acheive this you need to set
QApplication.setQuitOnLastWindowClosed(false);
I've attached an example where I illustrate the more proper way of
acheiving this.
In main() I initialize QApplication and later call exec(), tying
QApplication and all Qt Jambi related execution to the process' main
thread. In my JButton event handler, which is called from the AWT event
dispacth thread, I synchronize on QApplication.instance() (any instance
would do, this was just a conveniently available one), pass the code I
want executed to QApplication and wait().
The QApplication event loop will pick up my invoked later ExecuteQt
runnable and execute it in the correct thread. This also synchronizes on
QApplication.instance(). It then performs its tasks and calls
QDialog.exec(). Once its done, it passes execution back to the Swing
thread using QApplication.instance().notify().
This example runs again and again, with the correct fonts every time.
Hope this help your porting efforts
best regards,
Gunnar
import java.awt.event.*;
import java.awt.event.*;
import javax.swing.*;
import com.trolltech.qt.gui.*;
public class QDialogInSwing {
private static class ExecuteQt implements Runnable {
public void run() {
System.out.println("jambi: running \"later\"");
synchronized(QApplication.instance()) {
System.out.println("jambi: actual execution");
QDialog d = new QDialog();
QPushButton button = new QPushButton("Qt Button");
button.clicked.connect(d, "accept()");
QVBoxLayout layout = new QVBoxLayout(d);
layout.addWidget(button);
System.out.println("jambi: modal dialog launching...");
d.exec();
System.out.println("jambi: done... waking up swint thread...");
QApplication.instance().notify();
}
}
}
private static class LaunchQtFromSwingHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
synchronized(QApplication.instance()) {
System.out.println("swing: calling invoke later...\n");
QApplication.invokeLater(new ExecuteQt());
System.out.println("swing: waiting...\n");
try {
QApplication.instance().wait();
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("swing: done waiting...\n");
}
}
}
public static void main(String args[]) {
QApplication.initialize(args);
QApplication.setQuitOnLastWindowClosed(false);
JFrame f = new JFrame();
JButton b = new JButton("SwingButton");
f.getContentPane().add(b);
f.pack();
f.setVisible(true);
b.addActionListener(new LaunchQtFromSwingHandler());
QApplication.exec();
}
}
Message 3 in thread
Hi Gunnar,
You are great and your sample very usefull.
It's the fact I had to use a thread to launch my QDialog, run by
QApplication.invokeLater(). Doing this way has permitted to initialize the
QApplication only once in my main and solved my font issue.
Everything works now. It only remains for me to change all my swing screens...
Thanks a lot.
Paul.
Le Monday 26 November 2007 09:21:35, vous avez ÃcritÂ:
> private static class ExecuteQt implements Runnable {
> Â Â Â Â public void run() {
> Â Â Â Â Â Â System.out.println("jambi: running \"later\"");
> Â Â Â Â Â Â synchronized(QApplication.instance()) {
> Â Â Â Â Â Â Â Â System.out.println("jambi: actual execution");
> Â Â Â Â Â Â Â Â QDialog d = new QDialog();
> Â Â Â Â Â Â Â Â QPushButton button = new QPushButton("Qt Button");
> Â Â Â Â Â Â Â Â button.clicked.connect(d, "accept()");
>
> Â Â Â Â Â Â Â Â QVBoxLayout layout = new QVBoxLayout(d);
> Â Â Â Â Â Â Â Â layout.addWidget(button);
>
> Â Â Â Â Â Â Â Â System.out.println("jambi: modal dialog launching...");
> Â Â Â Â Â Â Â Â d.exec();
>
> Â Â Â Â Â Â Â Â System.out.println("jambi: done... waking up swint
> thread..."); QApplication.instance().notify();
> Â Â Â Â Â Â }
> Â Â Â Â }
>
> Â Â }