Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

WxPerl Next button

by saran73 (Initiate)
on Jan 04, 2013 at 16:30 UTC ( #1011675=perlquestion: print w/replies, xml ) Need Help??
saran73 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks. I'm writing an app to read data from XML that contains multiple choice question. I used 2 dialogs (one for the use user selecting the topic and another to show the question with answer choice using RadioBox). I'm not sure how to use the same button to show a question, wait for the user to select the answer and show the next question after he clicks next. Also, how can I update the choice string in the RadioBox for the next question? Thanks in advance for the help.

Replies are listed 'Best First'.
Re: WxPerl Next button
by jmlynesjr (Hermit) on Jan 04, 2013 at 20:00 UTC

    Refer to More wxPerl Examples now on Github. Specifically the and examples.

    You may need to create a custom dialog similar to pg225 that uses radio buttons rather than a list box. Look these examples over and post your code if you can.


    There's never enough time to do it right, but always enough time to do it over...

      Hi James, Thanks for your reply. I did use few of the examples from the github (very useful and thanks for sharing it). Here is the code: (input is at the end of the file)
      use strict; use warnings; use Wx; use Wx::Event qw( EVT_BUTTON ); use Wx qw[:everything]; use base qw/Wx::Frame/; # Inherit from Wx::Frame our %panel; my $selectedChapter; Main( @ARGV ); exit( 0 ); sub Main { my $app = Wx::SimpleApp->new; my $frame = Wx::Frame->new( undef, -1, "Test window", [ 100, 100 ], [ 800, 600 ], Wx::wxDEFAULT_FRAME_STYLE()|Wx::wxTAB_TRAVERSAL() ); MakeChaptersPanel( $frame ); $frame->SetSizer( Wx::BoxSizer->new( Wx::wxVERTICAL() ) ); $frame->GetSizer->Add( $panel{first}, 1, Wx::wxEXPAND() ); $frame->Show(1); $app->SetTopWindow($frame); $app->MainLoop; } ## end sub Main sub MakeChaptersPanel { my( $frame ) = @_; $panel{'first'} = Wx::Panel->new( $frame, -1, [ -1, -1 ], [ -1, -1], ); Wx::StaticText->new( $panel{'first'}, 1, "Answer Verification App", [50, 50] ); my $SHOWQUESTION_BTNID = 1; my $showQuestions = Wx::Button->new( $panel{'first'}, $SHOWQUESTION_BTNID, "Show Questions", [150,300] ); my %chapters; my $data_pos = tell DATA; # save the position while (<DATA>) { if ( m@<questionId>.*?(\d\d)(\d{4})</questionId>@) { $chapters{$1}++; } } seek DATA, $data_pos, 0; my @chapters; foreach my $chapter (keys %chapters) { push(@chapters,$chapter); } my $CHAPTER_RADIOBOX = 2; my $selectChapter = Wx::RadioBox->new($panel{'first'}, $ CHAPTER_RADIOBOX, "Select the Chapter", Wx::Point->new(100,100), wxDefaultSize, \@chap +ters, 1, wxRA_SPECIFY_COLS); $selectChapter->SetSelection(1); Wx::Event::EVT_BUTTON( $frame, $showQuestions, sub{\&ShowQuestions(@_, $selectChapter->GetStringSelection())}); return; } ## end sub MakePanels sub MakeQuestionsPanel { my( $frame ) = @_; $panel{'second'} = Wx::Panel->new( $frame, -1, [ -1, -1 ], [ -1, -1 ], ); $panel{'second'}->Hide(); my $NEXTQUESTION_BTNID = 2; my $nextQuestionbtn = Wx::Button->new( $panel{'second'}, $NEXTQUESTION_BTNID, "Next Questions", [150,300] ); my $insideQuestion = 0; my @answerChoices; my $correctAnswer; my $weightage; my $QUESTIONS_RADIOBOX = 3; while (<DATA>) { if ( m@<Question>@ ) { $insideQuestion = 1; print $_; next; } if ( m@</Question>@ ) { $insideQuestion = 0; my $questionChoices = Wx::RadioBox->new($panel{'second'}, $QUESTIONS_RADIOBOX, "Answer Choices +", Wx::Point->new(100,100), wxDefaultSize, \@answerChoices, 1, wxRA_SPECIFY_COLS); $questionChoices->SetStringSelection($correctAnswer); last; } if ( $insideQuestion ) { if ( m@<questionId>.*?(\d\d)(\d{4})</questionId>@) { if ( $1 != $selectedChapter) { $insideQuestion = 0; next; } } if ( m@<question>(.*?)</question>@ ) { print "$1\n"; my $questionText = Wx::StaticText->new( $panel{'secon +d'}, 1, "$1", [50, 70] ); } elsif ( m@<Answer\d>(.*?)</Answer\d>@ ) { push(@answerChoices,$1); } elsif ( m@<CorrectAnswer>(.*?)</CorrectAnswer>@ ) { $correctAnswer = $1; } elsif ( m@<weightage>(.*?)</weightage>@ ) { $weightage = $1; } print "$_"; } } return; } sub ShowQuestions { my ( $frame, $event, $mySelectedChapter ) = @_; my $button = $event->GetEventObject; my $label = $button->GetLabel(); $selectedChapter = $mySelectedChapter; $frame->SetTitle("Chapter " . $selectedChapter); MakeQuestionsPanel( $frame ); $panel{first}->Hide(); $panel{second}->Show(); $frame->GetSizer->Add( $panel{second}, 1, Wx::wxEXPAND() ); $frame->GetSizer->Layout(); } __DATA__ <Question> <questionId>TNHSCS010001</questionId> <question>Jenkins is primiary used of ........</question> <Answer1> Nightly Builds </Answer1> <Answer3> CI Builds </Answer3> <Answer4> Report Generation </Answer4> <Answer1> All the above </Answer1> <CorrectAnswer> CI Builds </CorrectAnswer> </Question> <Question> <questionId>TNHSCS010002</questionId> <question>CI builds are setup to ............</question> <Answer1> catch potentail build errors</Answer1> <Answer2> find bugs </Answer2> <Answer3> reduce build time </Answer3> <Answer4> None of the above </Answer4> <CorrectAnswer> catch potentail build errors </CorrectAnswer> </Question> <Question> <questionId>TNHSCS020001</questionId> <question>Jenkins is primiary used of ........</question> <Answer1> Nightly Builds </Answer1> <Answer3> CI Builds </Answer3> <Answer4> Report Generation </Answer4> <Answer1> All the above </Answer1> <CorrectAnswer> CI Builds </CorrectAnswer> </Question> <Question> <questionId>TNHSCS020002</questionId> <question>CI builds are setup to ............</question> <Answer1> catch potentail build errors</Answer1> <Answer2> find bugs </Answer2> <Answer3> reduce build time </Answer3> <Answer4> None of the above </Answer4> <CorrectAnswer> catch potentail build errors </CorrectAnswer> </Question>

        I second the use of Wx::SingleChoiceDialog or Wx::MultiChoiceDialog like jmlynesjr sugested.

        Parsing XML like you do is not a good choice, use a dedicated module, something like this:

        use strict; use warnings; use XML::Simple; use Data::Printer; my $data = do { local $/; <DATA> }; # slurp DATA my $ref = XMLin( $data, #KeyAttr => { Question => 'questionId' }, # unordered data ForceArray => ['item'], ContentKey => '-content' ); p $ref; __DATA__ <Questions> <Question> <questionId>TNHSCS010001</questionId> <question>Jenkins is primiary used of ...</question> <Answers correct="no">Nightly Builds</Answers> <Answers correct="yes">CI Builds</Answers> <Answers correct="no">Report Generation</Answers> <Answers correct="no">All the above</Answers> </Question> <Question> <questionId>TNHSCS010002</questionId> <question>CI builds are setup to ...</question> <Answers correct="yes">Catch potentail build errors</Answers> <Answers correct="no">Find bugs</Answers> <Answers correct="no">Reduce build time</Answers> <Answers correct="no">None of the above</Answers> </Question> </Questions>

        Notice that a valid XML must have a root tag. I also changed a little the structure...

        Regards, Stefan

Re: WxPerl Next button
by jmlynesjr (Hermit) on Jan 05, 2013 at 14:20 UTC

    After reviewing and running your code, and having read a zillion of theses posts now, I knew that a more learned Monk would suggest using one of the CPAN XML parsers. Thanks stefbz. I have not gotten into XML at all yet.

    I do think that you should be using a dialog(modal) rather than individual controls. I would start with the wxSingleChoiceDialog and use it to get my application logic correct. Build and popup the dialog, extract your answer, destroy the popup, then repeat for all of your questions. Then if you still want a different look and feel you could implement a custom dialog like the wxSingleChoiceDialog, but using radio boxes instead of a list. See for the wxSingleChoiceDialog example and for the PersonalRecordDialog custom dialog example.

    The next more complicated option would be to create a wxWizard. Unfortunately I haven't yet implemented the wxWizard example from the "wxBook" in my github examples.

    See also the wxDemo wxWizard and wxSingleChoiceDialog examples. I run Citrus Perl 5.16 and on my system these can be found at home/CitrusPerl/perl/vendor/bin/ Look under the Managed Windows and Dialogs sections.

    Please repost your working application to add to the example base.

    Update1:See if the following code can be integrated with your XML code.

    Update2:Just for completeness a wxWizard example follows.


    There's never enough time to do it right, but always enough time to do it over...

      Hi James/Stefan, Thanks for the valuable input. Since I have to print line-by-line as we select the correct answer (this app is just to verify the correct answers), I chose not to use XML parsers since anytime the actual XML file several additional nodes that I don't need in (both inside and outside the question node). I have made some good progress by destroying and recreating RadioBox when the user selects next button. After testing the code thoroughly, I will post it and you can modify (if required) and add it to the examples. Regards Saran

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1011675]
Front-paged by Arunbear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2017-06-23 02:43 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (533 votes). Check out past polls.