There is a properties dialog with a large number of input fields as follows:
Here is the header definition for the data.
// Way too much junk to pass back and forth.
// So let's make it all a class and then we can use class copy to move this stuff
// around.
class CGearParams
{
public:
double m_dBaseWidth; // width at base of tooth. This sets diameter of gear.
double m_dGearThick; // thickness of gear outer ring and hub
double m_dSpokeThick; // thickness of spokes [or disk of 1 spoke]
double m_dHubRadius; // radius of hub around shaft
double m_dHubThick; // thickness of the hub
double m_dRingWidth; // width of outer ring of gear
double m_dShaftRadius; // radius of shaft
int m_nHeightPct; // Height of tooth as percent of base
int m_nTopPct; // Top of tooth as percent of base
int m_nTeeth; // number of teeth
int m_nRadialSecPerTooth; // radial sections, per tooth
bool m_bSpiral; // spiral type gear?
bool m_bSpiralLeft; // Reverse the spiral
int m_nSpiralSections; // how many sections along height for spiral
int m_nSpiralAngle; // spiral angle - 0 = no spiral, 89degrees very shallow
int m_nSpokes; // how many spokes
int m_nSpokesPct; // spokes radial percent
// each spoke takes up this much of its angle
bool m_bRingGear; // Create a ring gear with teeth inside
};
//
// IITEM - integer item
// DITEM - double item
// CITEM - checkbox item
// IITEM( widget, member, min, max, default, name )
#define GEAR_OPTIONS_ITEMS
DITEM( gearThickBox, m_dGearThick,0.2 , 1.0, 0.5 , "Gear thickness" )
DITEM( spokeThickBox, m_dSpokeThick, .01,1.0 ,0.125 , "Spoke thickness" )
DITEM( shaftRadiusBox, m_dShaftRadius, .01,1.0 ,0.125 , "Shaft radius" )
DITEM( hubRadiusBox, m_dHubRadius, .01,1.0 ,0.25 , "Hub radius" )
DITEM( hubThickBox, m_dHubThick, .01,1.0 ,0.35 , "Hub thickness" )
DITEM( outerRingWidthBox, m_dRingWidth, .01,1.0 ,0.25 , "Outer ring width" )
CITEM( reverseCheck, m_bSpiralLeft,0 ,0 ,false , "Spiral to the left" )
IITEM( numTeethBox, m_nTeeth, 10, 60, 20, "Number of teeth" )
CITEM( spiralCheck, m_bSpiral,0 ,0 , false, "Spiral gear" )
IITEM( spokesBox, m_nSpokes,1 ,20 ,1 , "Number of spokes" )
IITEM( radialSectionsBox, m_nRadialSecPerTooth,1 , 10,4 , "Radial sections per tooth" )
IITEM( spiralDegreesBox, m_nSpiralAngle, 0, 89,45 , "Spiral angle in degrees" )
IITEM( spokesWidthPctBox, m_nSpokesPct,10 , 500, 10, "Spokes width %" )
IITEM( spiralSectionsBox, m_nSpiralSections,1 ,20 , 4, "Spiral sections" )
CITEM( ringGearCheck, m_bRingGear, 0, 0, false, "Make ring gear" )
DITEM( baseWidthBox, m_dBaseWidth, .01,1.0 ,.25 , "Base width of tooth" )
IITEM( heightPctBox, m_nHeightPct, 50,150 ,100 , "Height % of tooth" )
IITEM( topWidthPctBox, m_nTopPct, 20, 100, 50, "Top width % of tooth" )
The code to set the validators looks like this:
//
// define the macros to set the validators and the default values
// for the GUI items
#define IITEM( widget, member, min, max, default, name )
{ widget->setValidator( new QIntValidator( min, max, this, name ) );
widget->setInputMask( QString("0000") );
QString str; str.setNum(default); widget->setText( str ); m_params.member = default; }
//
#define DITEM( widget, member, min, max, default, name )
{ widget->setValidator( new QDoubleValidator( min, max, 3, this, name ) );
/*widget->setInputMask( QString("0.000") ); */
QString str; str.setNum(default); widget->setText( str ); m_params.member = default;}
//
#define CITEM( widget, member, min, max, default, name )
widget->setChecked( default ); m_params.member = default;
//
void GearOptionsDialog::setOptionsValidate()
{
GEAR_OPTIONS_ITEMS;
}
The code to check the validators looks like this:
// Check the validation and report any errors with an intelligent message
bool GearOptionsDialog::validateItem( QLineEdit* widget, const char* name, QString& mins, QString& maxs )
{
bool bOk = widget->hasAcceptableInput();
QString errstr;
if ( !bOk )
{
errstr = name;
errstr.append( " is out of range:n");
errstr.append( mins ); errstr.append( " - " ); errstr.append( maxs );
KMessageBox::information( parentWidget(), errstr, QString("Invalid Input") );
}
return bOk;
}
//
#undef IITEM
#undef DITEM
#undef CITEM
// define the macros to set the GUI items from the members
#define IITEM( widget, member, min, max, default, name )
/* bErrors |= !widget->hasAcceptableInput(); */
{QString mins;mins.setNum(min); QString maxs; maxs.setNum(max);
if ( !validateItem( widget, name, mins, maxs ) ) { bErrors=true; goto cleanup; } }
//
#define DITEM( widget, member, min, max, default, name )
/* bErrors |= !widget->hasAcceptableInput(); */
{QString mins;mins.setNum(min); QString maxs; maxs.setNum(max);
if ( !validateItem( widget, name, mins, maxs ) ) { bErrors=true; goto cleanup; } }
//
#define CITEM( widget, member, min, max, default, name )
//
bool GearOptionsDialog::validateData()
{
bool bErrors = false;
GEAR_OPTIONS_ITEMS;
cleanup:
return !bErrors;
}
hasAcceptableInput() works correctly now that the validator objects are “new” rather than being stack items. A misunderstanding about whether they were copied into the QLineEdit object. This code provides an intelligent popup box to fix any errors. The integer objects use input masks, but the double input mask didn’t allow valid input to be entered.
The validators appear to be working now. A future post will contain the valid project.
d