#!/usr/bin/perl -w
package WidgetView;
use Qt 2.0;
import Qt::app;
use lib '../aclock', '../dclock';
use Qt::slots 'button1Clicked()',
'checkBoxClicked(int)',
'radioButtonClicked(int)',
'sliderValueChanged(int)',
'listBoxItemSelected(int)',
'comboBoxItemActivated(int)',
'edComboBoxItemActivated(cstring)',
'lineEditTextChanged(cstring)',
'movieStatus(int)',
'movieUpdate(const \QRect)',
'spinBoxValueChanged(cstring)';
sub MOVIEFILENAME () { "perlqt.gif" }
@ISA = qw(Qt::Widget);
sub new {
my $self = shift->SUPER::new(@_);
my $col = Qt::Color->new;
# Set the window caption/title
$self->setCaption("PerlQt Widget Demo Application");
# Install an application-global event filter
$app->installEventFilter($self);
# Create a layout to position the widgets
my $topLayout = Qt::VBoxLayout->new($self, 10);
# Create a grid layout to hold most of the widgets
my $grid = Qt::GridLayout->new(6, 3);
# This layout will get all of the stretch
$topLayout->addLayout($grid, 10);
# Create a menubar
my $menubar = Qt::MenuBar->new($self);
$menubar->setSeparator(Qt::MenuBar::InWindowsStyle);
# Create an easter egg
Qt::ToolTip::add($menubar, Qt::Rect->new(0, 0, 2, 2), "easter egg");
my $popup;
$popup = Qt::PopupMenu->new;
my $id;
$id = $popup->insertItem("&New");
$popup->setItemEnabled($id, 0);
$id = $popup->insertItem("&Open");
$popup->setItemEnabled($id, 0);
$popup->insertSeparator();
$popup->insertItem("&Quit", $app, 'quit()', Qt::CTRL+Qt::Key_Q);
$menubar->insertItem("&File", $popup);
# Must tell the layout about a menubar in a widget
$topLayout->setMenuBar($menubar);
# Create an analog and a digital clock
my $aclock = AnalogClock->new($self);
my $dclock = DigitalClock->new($self);
$dclock->setMaximumWidth(200);
$grid->addWidget($aclock, 0, 2);
$grid->addWidget($dclock, 1, 2);
# Give the dclock widget a blue palette
$col->setRgb(0xaa, 0xbe, 0xff);
$dclock->setPalette(Qt::Palette->new($col));
# make tool tips for both of them
Qt::ToolTip::add($aclock, "custom widget: analog clock");
Qt::ToolTip::add($dclock, "custom widget: digital clock");
# Create a push button.
my $pb;
$pb = Qt::PushButton->new($self, "button1");
$pb->setText("Push button 1");
$pb->setFixedHeight($pb->sizeHint()->height());
$grid->addWidget($pb, 0, 0, $Qt::AlignVCenter);
$self->connect($pb, 'clicked()', 'button1Clicked()');
Qt::ToolTip::add($pb, "push button 1");
my $pm = Qt::Pixmap->new;
my $pix = $pm->load("perlqt.bmp");
if(!$pix) {
# Qt::MessageBox::information(0,
# "PerlQt Widgets Example",
# "Could not load the file \"perlqt.bmp\", which\n" .
# "contains an icon used...\n\n" .
# "The text \"line 42\" will be substituted.",
# Qt::MessageBox::Ok + Qt::MessageBox::Default );
}
# Create a label containing a QMovie
my $movielabel = $self->{'movielabel'} = Qt::Label->new($self, "label0");
my $movie = $self->{'movie'} = Qt::Movie->new(MOVIEFILENAME);
$movie->connectStatus($self, 'movieStatus(int)');
$movie->connectUpdate($self, 'movieUpdate(const \QRect)');
$movielabel->setFrameStyle(Qt::Frame::Box | Qt::Frame::Plain);
$movielabel->setMovie($movie);
$movielabel->setMargin(0);
$movielabel->setFixedSize(128+$movielabel->frameWidth()*2,
64 +$movielabel->frameWidth()*2);
$grid->addWidget($movielabel, 0, 1, Qt::AlignCenter);
Qt::ToolTip::add($movielabel, "movie");
# Create a group of check boxes
my $bg = Qt::ButtonGroup->new($self, "checkGroup");
$bg->setTitle("Check Boxes");
$grid->addWidget($bg, 1, 0);
# Create a layout for the check boxes
my $vbox = Qt::VBoxLayout->new($bg, 10);
$vbox->addSpacing($bg->fontMetrics()->height());
my @cb;
$cb[0] = Qt::CheckBox->new($bg);
$cb[0]->setText("Read");
$vbox->addWidget($cb[0]);
$cb[0]->setMinimumSize($cb[0]->sizeHint());
$cb[1] = Qt::CheckBox->new($bg);
$cb[1]->setText("Write");
$vbox->addWidget($cb[1]);
$cb[1]->setMinimumSize($cb[1]->sizeHint());
$cb[2] = Qt::CheckBox->new($bg);
$cb[2]->setText("Execute");
$cb[2]->setMinimumSize($cb[2]->sizeHint());
$vbox->addWidget($cb[2]);
$bg->setMinimumSize($bg->childrenRect()->size());
$vbox->activate();
$self->{'cb'} = \@cb;
$self->connect($bg, 'clicked(int)', 'checkBoxClicked(int)');
Qt::ToolTip::add($cb[0], "check box 1");
Qt::ToolTip::add($cb[1], "check box 2");
Qt::ToolTip::add($cb[2], "check box 3");
# Create a group of radio buttons
my $rb;
$bg = Qt::ButtonGroup->new($self, "radioGroup");
$bg->setTitle("Radio buttons");
$grid->addWidget($bg, 1, 1);
# Create a layout for the radio buttons
$vbox = Qt::VBoxLayout->new($bg, 10);
$vbox->addSpacing($bg->fontMetrics()->height());
$rb = Qt::RadioButton->new($bg);
$rb->setText("&AM");
$rb->setChecked(1);
$vbox->addWidget($rb);
$rb->setMinimumSize($rb->sizeHint());
Qt::ToolTip::add($rb, "radio button 1");
$rb = Qt::RadioButton->new($bg);
$rb->setText("&FM");
$vbox->addWidget($rb);
$rb->setMinimumSize($rb->sizeHint());
Qt::ToolTip::add($rb, "radio button 2");
$rb = Qt::RadioButton->new($bg);
$rb->setText("&Short Wave");
$vbox->addWidget($rb);
$rb->setMinimumSize($rb->sizeHint());
$vbox->activate();
$self->connect($bg, 'clicked(int)', 'radioButtonClicked(int)');
Qt::ToolTip::add($rb, "radio button 3");
# Create a list box
my $lb = Qt::ListBox->new($self, 'listBox');
for(my $i = 0; $i < 100; $i++) {
$lb->insertItem(($i == 42 && $pix) ? $pm : "line $i");
}
$grid->addMultiCellWidget($lb, 2, 4, 0, 0);
$self->connect($lb, 'selected(int)', 'listBoxItemSelected(int)');
Qt::ToolTip::add($lb, "list box");
$vbox = Qt::VBoxLayout->new(8);
$grid->addLayout($vbox, 2, 1);
# Create a slider
my $sb = Qt::Slider->new(0, 300, 1, 100, Qt::Slider::Horizontal,
$self, "Slider");
$sb->setTickmarks(Qt::Slider::Below);
$sb->setTickInterval(10);
$sb->setFocusPolicy(Qt::Widget::TabFocus);
$sb->setFixedHeight($sb->sizeHint()->height());
$vbox->addWidget($sb);
$self->connect($sb, 'valueChanged(int)', 'sliderValueChanged(int)');
Qt::ToolTip::add($sb, "slider");
# Create a combo box
my $combo = Qt::ComboBox->new(0, $self, "comboBox");
$combo->insertItem("darkBlue");
$combo->insertItem("darkRed");
$combo->insertItem("darkGreen");
$combo->insertItem("blue");
$combo->insertItem("red");
$combo->setFixedHeight($combo->sizeHint()->height());
$vbox->addWidget($combo);
$self->connect($combo, 'activated(int)', 'comboBoxItemActivated(int)');
Qt::ToolTip::add($combo, "read-only combo box");
# Create an editable combo box
my $edCombo = Qt::ComboBox->new(1, $self, "edComboBox");
$edCombo->insertItem("Permutable");
$edCombo->insertItem("Malleable");
$edCombo->insertItem("Adaptable");
$edCombo->insertItem("Alterable");
$edCombo->insertItem("Inconstant");
$edCombo->setFixedHeight($edCombo->sizeHint()->height());
$vbox->addWidget($edCombo);
$self->connect($edCombo, 'activated(cstring)', 'edComboBoxItemActivated(cstring)');
Qt::ToolTip::add($edCombo, "editable combo box");
$edCombo->setAutoCompletion(1);
$vbox->addStretch(1);
$vbox = Qt::VBoxLayout->new(8);
$grid->addLayout($vbox, 2, 2);
# Create a spin box
my $spin = Qt::SpinBox->new(0, 10, 1, $self, "spin");
$spin->setSuffix(" mm");
$spin->setSpecialValueText("Auto");
$spin->setMinimumSize($spin->sizeHint());
$self->connect($spin, 'valueChanged(cstring)', 'spinBoxValueChanged(cstring)');
Qt::ToolTip::add($spin, "spin box");
$vbox->addWidget($spin);
$vbox->addStretch(1);
# Create a multi line edit
my $mle = Qt::MultiLineEdit->new($self, "multiLineEdit");
$grid->addMultiCellWidget($mle, 3, 3, 1, 2);
$mle->setMinimumHeight($mle->fontMetrics()->height()*3);
$mle->setText("This is a QMultiLineEdit widget,\n" .
"useful for small multi-line\n" .
"input fields.");
Qt::ToolTip::add($mle, "multi line editor");
# Create a single line edit
my $le = Qt::LineEdit->new($self, "lineEdit");
$grid->addMultiCellWidget($le, 4, 4, 1, 2);
$le->setFixedHeight($le->sizeHint()->height());
$self->connect($le, 'textChanged(cstring)', 'lineEditTextChanged(cstring)');
Qt::ToolTip::add($le, "single line editor");
# Create a horizontal line (sort of QFrame) above the message line
my $separator = Qt::Frame->new($self, "separatorLine");
$separator->setFrameStyle(Qt::Frame::HLine | Qt::Frame::Sunken);
$separator->setFixedHeight($separator->sizeHint()->height());
$grid->addMultiCellWidget($separator, 5, 5, 0, 2);
Qt::ToolTip::add($separator, "tool tips on a separator! wow!");
$grid->setRowStretch(0,0);
$grid->setRowStretch(1,0);
$grid->setRowStretch(2,0);
$grid->setRowStretch(3,1);
$grid->setRowStretch(4,1);
$grid->setRowStretch(5,0);
$grid->setColStretch(0,1);
$grid->setColStretch(1,1);
$grid->setColStretch(2,1);
# Create an label and a message in a plain widget
# The message is updated when buttons are clicked etc.
my $hbox = Qt::HBoxLayout->new();
$topLayout->addLayout($hbox);
my $msgLabel = Qt::Label->new($self, "msgLabel");
$msgLabel->setText("Message:");
$msgLabel->setAlignment(Qt::AlignCenter);
$msgLabel->setFixedSize($msgLabel->sizeHint());
$hbox->addWidget($msgLabel);
Qt::ToolTip::add($msgLabel, "label 1");
my $msg = $self->{'msg'} = Qt::Label->new($self, "message");
$msg->setFrameStyle(Qt::Frame::Panel | Qt::Frame::Sunken);
$msg->setAlignment(Qt::AlignCenter);
$msg->setFont(Qt::Font->new("times",12,Qt::Font::Bold));
$msg->setText("Message");
$msg->setFixedHeight($msg->sizeHint()->height());
$msg->setText("");
$hbox->addWidget($msg, 5);
Qt::ToolTip::add($msg, "label 2");
$topLayout->activate();
return $self;
}
sub setStatus {
shift->{'msg'}->setText(shift);
}
sub button1Clicked {
shift->{'msg'}->setText("The first push button was clicked");
}
sub movieUpdate {
# Uncomment this to test animated icons on your window manager
# $self->setIcon($movie->framePixmap());
}
sub movieStatus {
my $self = shift;
my $s = shift;
my $movielabel = $self->{'movielabel'};
if($s == Qt::Movie::SourceEmpty) {
$movielabel->setText("Could not load\n" . MOVIEFILENAME);
$movielabel->setAlignment(Qt::AlignCenter);
$movielabel->setBackgroundColor($self->backgroundColor);
} elsif($movielabel->movie()) {
$movielabel->setBackgroundMode(Qt::Widget::NoBackground);
}
}
sub checkBoxClicked {
my $self = shift;
my $id = shift;
my($msg, $cb) = @$self->{'msg', 'cb'};
my $chk = "";
$chk .= $cb->[0]->isChecked() ? "r" : "-";
$chk .= $cb->[1]->isChecked() ? "w" : "-";
$chk .= $cb->[2]->isChecked() ? "x" : "-";
$msg->setText("Check box $id clicked : $chk");
}
sub edComboBoxItemActivated {
shift->{'msg'}->setText("Editable Combo Box set to " . shift);
}
sub radioButtonClicked {
shift->{'msg'}->setText("Radio button #" . shift . " clicked");
}
sub listBoxItemSelected {
shift->{'msg'}->setText("List box item " . shift . " selected");
}
sub sliderValueChanged {
my $self = shift;
my $value = shift;
my $msg = $self->{'msg'};
$msg->setText("Movie set to $value% of normal speed");
$self->{'movie'}->setSpeed($value);
}
sub comboBoxItemActivated {
my $self = shift;
my $index = shift;
my $msg = $self->{'msg'};
$msg->setText("Combo box item $index activated");
my(@coloridx) = (Qt::darkBlue, Qt::darkRed, Qt::darkGreen,
Qt::blue, Qt::red);
Qt::Application::setWinStyleHighlightColor($coloridx[$index]);
}
sub lineEditTextChanged {
shift->{'msg'}->setText("Line edit text: " . shift);
}
sub spinBoxValueChanged {
shift->{'msg'}->setText("Spin box value: " . shift);
}
#
# All application events are passed throught this event filter.
# We're using it to display some information about a clicked
# widget (right mouse button + CTRL).
#
#{
# my $identify_now = 1;
# sub eventFilter {
# my $self = shift;
# my($obj, $event) = @_;
#
# if($event->type() == Qt::Event_MouseButtonPress && $identify_now) {
# my $e = Qt::MouseEvent->cast($event);
# if($e->button() == Qt::RightButton &&
# ($e->state() & Qt::ControlButton) != 0) {
# my $str = "The clicked widget is a\n";
# $str .= $obj->className();
# $str .= "\nThe widget's name is\n";
# $str .= $obj->name() || "<no name>";
# $identify_now = 0;
# Qt::MessageBox::message("Identify Widget", $str, 0, Qt::Widget->cast($obj));
# }
package main;
use Qt 2.0;
import Qt::app;
$w = WidgetView->new;
$app->setMainWidget($w);
$w->show();
exit $app->exec();