#!/usr/bin/perl -w package WidgetView; use Qt 2.0; import Qt::app; use lib '../aclock', '../dclock'; use AnalogClock; use DigitalClock; 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() || ""; # $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();