A simple table

The basic properties of the tableselect element are #header which accepts an array of key => value pairs to generate the header from and #options, which receives an array of rows.

The basic structure looks like the following:

$header = array(
  'field1' => 'Title of field 1',
  'field2' => 'Title of field 2',
);

$options['some_unique_id'] = array(
  'field1' => 'Value of field 1',
  'field2' => 'Value of field 2',
);

The tableselect element relies on the keys to match columns with the appropriate header. The element will behave like the #checkboxes type. You'll get an array of values in your submit function, with the checked ones set to nonzero so you can array_filter them to get the checked rows.

function example_elements_form() {
  $form = array();

  $header = array(
    'title' => t('Title'),
    'author' => t('Author'),
  );

  $query = "SELECT n.nid, n.title, u.name FROM {node} n INNER JOIN {users} u ON n.uid = u.uid";
  $result = pager_query(db_rewrite_sql($query));

  while($partial_node = db_fetch_object($result)) {
    $options[$partial_node->nid] = array(
      'title' => check_plain($partial_node->title),
      'author' => check_plain($partial_node->name),
    );
  }

  if (!empty($options)) {
    $form['nodes'] = array(
      '#type' => 'tableselect',
      '#header' => $header,
      '#options' => $options,
    );

    $form['pager'] = array('#value' => theme('pager'));

    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Submit'),
    );

  }
  return $form;
}

Which results in:

Example table