How can I show a button in WordPress but make it unclickable unless logged in?

You didn’t provide any code so I’ll give you some pseudo code and you make of it what you will:

Your HTML button:

<a href="<?php echo $download_url; ?>" class="download-button<?php echo $is_disabled; ?>">Download</a>

Now, you’re going to want to write some CSS style rules for the following:

.download-button{}
.download-button.disabled{}

Make one look like a bright, vibrant, useable button, the make the disabled look dull and unusable, because it won’t be.

Finally, in your PHP/template you want to run the following somewhere before you load the HTML for the button:

if( is_user_logged_in() ) :
    $download_url="https://thedomain.com/file-path/to-your/downloadable-file.pdf";
    $is_disabled  = '';
else :
    $download_url="";
    $is_disabled  = ' disabled';
    //notice that there's a space at the beginning of ' disabled'
    //that's so the two classes don't merge into one string when you echo it out.
endif;

So here’s what’s happening.

First, we’re withholding the value for the download from visitors, because someone tech savvy could very easily just look at the source code and grab the download URL, so we use php variables to set us up to provide different information to the HTML as the page is rendered as we run a conditional check on whether or not the visitor is logged in. That’s what the PHP is doing.

The CSS just uses the .disabled class to make the button look unappealing and make it look inactive. People can click on it all they like but since they’re not logged in it won’t have an HREF value.

Now you didn’t ask, but you could also get fancier and add some jQuery like so in your main scripts folder:

if( $( '.download-button.disabled' ).length > 0 ) {
    $( '.download-button.disabled' ).on( 'click', function(e) {
        e.preventDefault();
        alert( 'Please sign up to our site if you would like access to downloads.' );
    } );
}

What that does is prevent the link/button from executing the default behaviour if it has the .disabled class and I threw in an alert message for good measure. That’d look half assed so you’d probably want to make a pop up or a slide out message with a better call to action and maybe a link to the form and stuff.