Skip to content

For Developers elabScan

FabianZ edited this page Apr 11, 2024 · 7 revisions

Abstract:

Table of contents:

Requirements

Miniconda environment

  • To create a new environment to work with: conda create --name elabScan_v1_xxx python=3.9

  • To activate the new environment: conda activate elabScan_v1_xxx

  • To start VSCode: code

Convert the Resourcefile

  • pip install pyqt6rc
  • pyside6-rcc -o Resourcefile_rc.py Resourcefile.qrc

Convert UI to Python file

  • pyside6-uic MainWindow.ui -o main_window.py

Convert the project to an executable

  • pip install auto-py-to-exe
  • auto-py-to-exe
  • Script location: Main python file
  • Onefile: "One directory"
  • Icon: Leave blank
  • Additional Files:
    • Output folder with errorlog.txt
    • config.txt
    • Ui_MainWindow.py
    • Gui_GetSet.py
    • Resourcefile_rc.py
  • Settings:
    • Output Directory: Whatever you want
  • Convert

Python packages

Python version 3.9 is working, 3.10 and above has some issues with Pillow 9.5

  • PyQT5 (elabScan version 1.61 or lower)
    Working version: PyQt5-5.15.9-cp37-abi3-win_amd64.whl
    pip install pyqt5

  • PySide6(elabScan version 1.618 or higher)
    Working version: PySide6_Addons-6.4.2-cp37-abi3-win_amd64.whl
    pip install PySide6

  • Pillow/PIL: For writing on images etc.
    Working version: Pillow-9.5.0
    pip install Pillow==9.5.0

  • Pandas
    Working version: pandas-1.3.5-cp37-cp37m-win_amd64.whl
    pip install pandas

  • qrcode: QRcode manipulation
    Working version: qrcode-7.4.2-py3-none-any.whl
    pip install qrcode

  • CV2: Powerful library for qrcode detection and other things.
    Working version: opencv_python-4.7.0.68-cp37-abi3-win_amd64.whl
    pip install opencv-python

  • Pyzbar
    Working version: pyzbar-0.1.9-py2.py3-none-win_amd64.whl
    pip install pyzbar

  • Openpyxl
    Working version: openpyxl-3.1.1-py2.py3-none-any.whl
    pip install openpyxl

  • Docx (elabScan version 1.61 or lower)
    Working version: filename=python_docx-0.8.11-py3-none-any.whl
    pip install python-docx

  • elabapy: API for elabFTW (elabScan version 1.61 or lower)
    Working version: elabapy-1.0.0-py3-none-any.whl
    pip install elabapy

  • elabapi: API for elabFTW (elabScan version 1.618 or higher)
    Working version: elabapi_python-0.5.1-py3-none-any.whl
    pip install elabapi-python

  • brother_ql: Brother API (elabScan version 1.618 or higher)
    Working version: brother_ql-0.9.4 future-0.18.3 packbits-0.6 pyusb-1.2.1
    pip install --upgrade brother_ql

  • Cairosvg: Convert SVG to PNG (elabScan version 1.618 or higher)
    Working version: cairoSVG-2.7.1-py3-none-any.whl
    pip install cairosvg

  • requests: Needed for getting the info from PubchemID (elabScan version 1.6180 or higher)
    Working version: requests-2.31.0-py3-none-any.whl
    pip install requests

Summary

pip install PySide6 Pillow==9.5.0 pandas qrcode opencv-python pyzbar openpyxl elabapi-python cairosvg
pip install --upgrade brother_ql

Requirements.txt (needs to be updated)

PySide6
Pillow
pandas
qrcode
opencv-python
pyzbar
openpyxl
python-docx
elabapy
brother_ql

pip install -r requirements.txt

Problems with Windows

The following message might appear:

OSError: no library called "cairo-2" was found
no library called "cairo" was found
no library called "libcairo-2" was found
cannot load library 'libcairo.so.2': error 0x7e.  Additionally, ctypes.util.find_library() did not manage to locate a library called
 'libcairo.so.2'
cannot load library 'libcairo.2.dylib': error 0x7e.  Additionally, ctypes.util.find_library() did not manage to locate a library cal
led 'libcairo.2.dylib'
cannot load library 'libcairo-2.dll': error 0x7e.  Additionally, ctypes.util.find_library() did not manage to locate a library calle
d 'libcairo-2.dll'

pip install pipwin

pipwin install cairocffi

Might fix the problem.

LabelPrinter connection.

The python package brother_ql can be used for printing with our LabelPrinter.

https://github.com/pklaus/brother_ql/issues/89
brother_ql --printer tcp://XXX.XXX.XX.XX:9100 --model QL-1050 print -l 62 myQR.png

A working example of the print functionality in a python program (resizing seems to not work.. but, is also not really necessary).

from PIL import Image
from brother_ql.conversion import convert
from brother_ql.backends.helpers import send
from brother_ql.raster import BrotherQLRaster

im = Image.open(r'D:\...\myQR.png')
#im.resize((620, 620)) 


def get_concat_h(im1, im2):
    dst = Image.new('RGB', (im1.width + im2.width, im1.height))
    dst.paste(im1, (0, 0))
    dst.paste(im2, (im1.width, 0))
    return dst

combimg = get_concat_h(im, im)

combimg.show()



backend = 'network' 
model = 'QL-1050' # your printer model.
printer = 'tcp://XXX.XXX.XX.XX:9100'    # Get these values from the Windows usb driver filter.  Linux/Raspberry Pi uses '/dev/usb/lp0'.

qlr = BrotherQLRaster(model)
qlr.exception_on_warning = True

instructions = convert(

        qlr=qlr, 
        images=[combimg],    #  Takes a list of file names or PIL objects.
        label='62', 
        rotate='0',    # 'Auto', '0', '90', '270'
        threshold=70.0,    # Black and white threshold in percent.
        dither=False, 
        compress=False, 
        red=False,    # Only True if using Red/Black 62 mm label tape.
        dpi_600=False, 
        hq=True,    # False for low quality.
        cut=True

)

send(instructions=instructions, printer_identifier=printer, backend_identifier=backend, blocking=True)

UI

UI Object description

Home

  1. QPushButton HomeCreate_button
  2. QPushButton HomeSearch_button
  3. QPushButton HomeScan_button
  4. QTabWidget Home_tab - QWidget Home_Home_tab
  5. QTabWidget Home_tab - QWidget Advanced_Home_tab
  6. QTabWidget Main_tab - QWidget Home_Main_tab
  7. QTabWidget Main_tab - QWidget Create_Main_tab
  8. QTabWidget Main_tab - QWidget Search_Main_tab
  9. QTabWidget Main_tab - QWidget Scan_Main_tab
  10. QTabWidget Main_tab - QWidget Log_Main_tab
  11. QTabWidget Main_tab - QWidget About_Main_tab
  1. QPushButton HomeLog_button
  2. QPushButton HomeAbout_button
  3. QPushButton HomeAddChemical_button
  4. QPushButton HomeAddEquipment_button

Create SampleID

  1. QLineEdit Decrypt_lineEdit
  2. QPushButton Decrypt_button
  3. QLabel DecryptResponse_label
  4. QPushButton SampleidBack1_button
  5. QPushButton SampleidForward1_button
  6. QTabWidget SampleID_tab - QWidget IDdecryption_SampleID_tab
  7. QTabWidget SampleID_tab - QWidget MandInfo_SampleID_tab
  8. QTabWidget SampleID_tab - QWidget SampleNumber_SampleID_tab
  9. QTabWidget SampleID_tab - QWidget GHS_SampleID_tab
  10. QTabWidget SampleID_tab - QWidget Disposal_SampleID_tab
  11. QTabWidget SampleID_tab - QWidget AddInformation_SampleID_tab
  12. QTabWidget SampleID_tab - QWidget ElabFTW_SampleID_tab
  13. QTabWidget SampleID_tab - QWidget Finish_SampleID_tab
  1. QLineEdit FirstName_lineEdit
  2. QLineEdit LastName_lineEdit
  3. QLineEdit Supervisor_lineEdit
  4. QDateEdit Current_dateEdit
  5. QDateEdit Expiration_dateEdit
  6. QPushButton SampleidBack2_button
  7. QPushButton SampleidForward2_button
  1. QRadioButton Single_radioButton
  2. QRadioButton Batch_radioButton
  3. QCheckBox SubSample1_checkBox
  4. QCheckBox SubSample2_checkBox
  5. QSpinBox Samplenumber1_spinBox
  6. QSpinBox Subsample1_spinBox
  7. QSpinBox Samplenumber2_spinBox
  8. QSpinBox Samplenumber3_spinBox
  9. QSpinBox Subsample2_spinBox
  10. QSpinBox Subsample3_spinBox
  11. QPushButton SampleidBack3_button
  12. QPushButton SampleidForward3_button
  1. QCheckBox Explos_checkBox
  2. QCheckBox Flamme_checkBox
  3. QCheckBox Rondflam_checkBox
  4. QCheckBox Acid_checkBox
  5. QCheckBox Skull_checkBox
  6. QCheckBox Exclam_checkBox
  7. QCheckBox Silhouette_checkBox
  8. QCheckBox Pollu_checkBox
  9. QPushButton SampleidBack4_button
  10. QPushButton SampleidForward4_button
  1. RadioButton NoIdea_radioButton
  2. RadioButton NonHarzardous_radioButton
  3. RadioButton ContaminatedSolids_radioButton
  4. RadioButton HalogenatedSolvents_radioButton
  5. RadioButton HalogenFreeSolvents_radioButton
  6. RadioButton SpecialPrecautions_radioButton
  7. QPushButton SampleidBack5_button
  8. QPushButton SampleidForward5_button
  1. QTableWidget AddInformation_tableWidget
  2. QPushButton SampleidBack6_button
  3. QPushButton SampleidForward6_button
  1. QPushButton ElabFTW_button
  2. QPushButton Foldersave_button
  3. QPushButton Save_button
  4. QComboBox PrintLayout_comboBox
  5. QPushButton Print_button
  6. QPushButton SampleidBack7_button
  7. QPushButton SampleidForward7_button
  8. QLabel ElabFTWOutput1_label
  9. QLabel ElabFTWOutput2_label
  1. QPushButton Reset_button
  2. QPushButton SampleidBack8_button
  3. QPushButton SampleidForward8_button

Search a SampleID/UserID

  1. QLineEdit SearchID_lineEdit
  2. QPushButton SearchID_pushButton
  3. QTextBrowser SearchID_textBrowser

Scan a QR-code

  1. QPushButton ScanQR_button
  2. QPushButton ShowQR_button
  3. QPushButton ScanToCreate_button
  4. QTextBrowser ScanResult_textBrowser

Logs

  1. QTextBrowser Log_textBrowser

About

  1. QLabel About_label

Main program

Python files

  • elabScan_v161xx.py: The main python file which will be executed. Imports:
    • Ui_MainWindow.py: The GUI of the Main window. Imports:
      • Resourcefile_rc.py: The resource file with all images.
    • StandardFunctionalities.py: Standard functionalities that are used by many of the other classes.
    • Gui_GetSet.py: Gets and sets parameters of the GUI, changes also the tabs with a lambda function.

Global folders

  • pythonfolder: The main directory where the program is executed.
  • outputfolder: The Output folder in the pythonfolder. Files:
    • errorlog.txt: If the program would not start, a logfile will be produced.

Classes

Ui_MainWindow

This is the class that was created from the .ui file.

Gui

Inherits: QMainWindow, Ui_MainWindow, Gui_GetSet

  • get_allselfs(self):

    """
    Prints all the current values of instance variables (self attributes).
    
    Attributes:
    - self.is_initial (bool): Flag indicating if initials are available.
    - self.initial (str): User abbreviation generated from first and last names.
    - self.is_singlesubsample (bool): Flag indicating the presence of single subsamples.
    - self.is_batchsubsample (bool): Flag indicating the presence of batch subsamples.
    - self.is_batch (bool): Flag indicating if in batch sample mode.
    - self.ghsdict (dict): Dictionary containing GHS values.
    - self.disposal (str): Disposal information.
    - self.shortday (str): Abbreviation of the current day.
    - self.shortmonth (str): Abbreviation of the current month.
    - self.shortyear (str): Abbreviation of the current year.
    """
  • decrypt_abbr(self, userid):

    """
    Translates an abbreviation of a user or sample ID to the lineedits.
    
    Parameters:
    - userid (pd.DataFrame): DataFrame containing user or sample ID information.
    
    Raises:
    - Exception: If the input is too short to be interpreted.
    
    Returns:
    None
    """
  • encrypt_abbr(self, userid):

    """
    Translate the name to a user abbreviation.
    
    This method takes the first name and last name entered by the user, looks
    up the corresponding user ID in the provided 'userid' DataFrame, and returns
    the user abbreviation. If the user is found in the DataFrame, it returns
    the uppercase user ID. Otherwise, it generates an abbreviation using the
    first letters of the first and last names.
    
    Args:
    userid (pd.DataFrame): DataFrame containing user information.
    
    Returns:
    str: User abbreviation.
    """
  • encrypt_date(self):

    """
    Translate the date to its abbreviation.
    
    This method extracts the year, month, and day from the current date and
    translates each component to its corresponding abbreviation. It returns a
    tuple containing the abbreviated year, month, and day.
    
    Returns:
    Tuple[str, str, str]: A tuple containing the abbreviated year, month, and day.
    """
  • namedate_update(self, userid):

    """
    Update the Initial and date by any change of any of the fields.
    
    Args:
    userid (str): The user ID for encryption.
    
    Returns:
    None.
    """
  • subsamplesingle_change(self):

    """
    Change the state of single subsamples.
    
    This method toggles the state of single subsamples based on the visibility
    of certain UI elements. It updates the 'self.is_singlesubsample' attribute
    and adjusts the visibility of related UI elements accordingly.
    
    Returns:
    None.
    """
  • subsamplebatch_change(self):

    """
    Change the state of batch subsamples.
    
    This method toggles the state of batch subsamples based on the visibility
    of certain UI elements. It updates the 'self.is_batchsubsample' attribute
    and adjusts the visibility of related UI elements accordingly.
    
    Returns:
    None.
    """
  • switch_singlebatch(self):

    """
    Switch between single and batch sample modes.
    
    This method toggles between single and batch sample modes based on the
    selection of the corresponding radio button. It updates the 'self.is_batch'
    attribute and logs the mode change.
    
    Returns:
    None.
    """        
  • ghs_change(self, ghsdictkey, checkboxobject):

    """
    Change a GHS value in the GHS dictionary.
    
    Args:
    ghsdictkey (str): The key corresponding to the GHS value.
    checkboxobject (QCheckBox): The checkbox object representing the GHS value.
    
    Returns:
    None.
    """
  • disposal_change(self, disposalstring):

    """
    Change the disposal string.
    
    Args:
    disposalstring (str): The new disposal string.
    
    Returns:
    None.
    """
  • encrypt_samplenumber(self):

    """
    Get the samplenumber(s) with potentially its subsamplenumber(s).
    
    This method retrieves sample numbers and subsample numbers based on user input.
    It ensures that the entered values are within a valid range and handles batch
    and single sample scenarios accordingly. The resulting sample numbers and
    subsample numbers are stored in 'self.samplenumberlist' and 'self.subsamplenumberlist'.
    
    Returns:
    None.
    """
  • create_sampletable(self):

    """
    Create the sampleID table with buttons.
    
    This method populates the sampleID table in the GUI with sample information.
    It retrieves necessary data using 'get_allselfs()' and iterates over the sample
    numbers to create labels with short names and numbers. The information is then
    added to the 'AddInformation_tableWidget'.
    
    Returns:
    None.
    """
  • get_pdsamples(self):

    """
    Generate a pandas DataFrame for all samples.
    
    This method collects information from the GUI elements and creates a DataFrame
    containing sample-related information. It extracts data such as sample IDs,
    custom sample names, additional comments, and boolean values for ElabFTW, Save PNG,
    and Print. The DataFrame is then populated with this information.
    
    Returns:
    None. The method updates the 'df' attribute with the generated DataFrame.
    """
  • save_folder(self):

    """
    Select a folder for saving the QR code images.
    
    This method opens a dialog for selecting a folder and sets the 'savefolder' attribute
    to the chosen path. It also logs the changes and updates labels in the GUI accordingly.
    
    Raises:
    - If an error occurs during the folder selection, an error message is logged,
    and error labels are updated in the GUI.
    
    Note:
    - If the folder selection is canceled, the method does not change the 'savefolder' attribute.
    - If the selected folder is empty, the default output folder is used.
    
    Returns:
    None. The method updates the 'savefolder' attribute based on the user's choice and logs the changes.
    """
  • qr_create(self):

    """
    Generate QR code images with additional labels.
    
    This method performs the following steps:
    1. Retrieves sample data using the 'get_pdsamples' method.
    2. Iterates through the sample data and creates a QR code for each entry.
    3. Adds labels to the QR code, including Shortname, Username, and GHS symbols.
    4. Combines all components into a single image and appends it to the 'qrlist' attribute.
    
    Note:
    - The Shortname and Username labels are rotated 90 degrees for better layout.
    - GHS symbols are added based on the hazard information in the sample data.
    
    Returns:
    None. The method generates QR codes and updates the 'qrlist' attribute, and there is no explicit return value.
    """
  • save_qrcodes(self):

    """
    Save QR codes based on the 'SaveList' in the DataFrame.
    
    This method performs the following steps:
    1. Calls the 'qr_create' method to generate QR codes.
    2. Iterates through the generated QR codes and saves them based on the 'SaveList' in the DataFrame.
    3. Logs the saved QR codes and updates labels in the GUI.
    
    Returns:
    None. The method saves QR codes to the specified folder and updates log information.
    """
  • elabftwbody_create(self):

    """
    Process sample data and create a list of dictionaries for eLabFTW.
    
    This method performs the following steps:
    1. Retrieves sample data using the 'get_pdsamples' method.
    2. Initializes an empty list 'elablist' to store dictionaries for eLabFTW.
    3. Iterates through the sample data and creates dictionaries for each sample.
    4. Each dictionary contains tags, title, body, and metadata fields for eLabFTW.
    5. Appends each dictionary to 'elablist'.
    
    Note:
        - The sample data is expected to be available in the global variable 'df'.
        - The list of sub-sample numbers is expected to be available in the global variable 'subsamplenumberlist'.
        - The list of sample numbers is expected to be available in the global variable 'samplenumberlist'.
    
    Returns:
    None. The method processes the sample data and populates the 'elablist' variable.
    """
  • sampleid_to_elabftw(self):

    """
    Upload sample data to eLabFTW.
    
    This method performs the following steps:
    1. Generates QR codes and saves them as PNG images.
    2. Creates a dictionary for eLabFTW data based on sample information.
    3. Configures the eLabFTW API client using the provided API key and base URL.
    4. Initializes the eLabFTW ItemsApi for working with eLabFTW items.
    5. Iterates through the sample data, creates new items in eLabFTW, and modifies their properties.
    
    Note:
    - The configuration information, such as API key, base URL, and category ID, is expected to be
    available in the global variable 'configdict'.
    - The sample data is expected to be available in the global variable 'elablist'.
    - QR codes are generated using the 'qr_create' method.
    - eLabFTW data is created using the 'elabftwbody_create' method.
    
    Returns:
    None. The method performs API requests to create and modify items, 
    and there is no explicit return value.
    
    Inputs:
    - self: The instance of the class containing this method.
    """
  • print_qrcodes(self):

    """
    Print QR codes using a Brother QL label printer.
    
    This method performs the following steps:
    1. Generates QR codes using the 'qr_create' method.
    2. Combines the generated QR codes based on the selected layout.
    3. Resizes the combined image to the specified target width.
    4. Prints the resized image on a Brother QL label printer.
    
    Note:
    - The layout options include "15 mm", "20 mm", "30 mm", and "60 mm".
    - The target width is set to 62 mm with a DPI of 300.
    - The 'combine_images' function arranges QR codes based on the selected layout.
    - The 'resize_image' function resizes an image while maintaining its aspect ratio.
    - The Brother QL label printer configuration (model, printer address) is specified in the method.
    
    Returns:
    None. The method performs image processing and printing actions, and there is no explicit return value.
    """
  • reset_ceram(self):

    """
    Restart the Ceram application.
    
    This method restarts the Ceram application by replacing the current process with a new
    instance of the Python interpreter running the same script. It effectively terminates
    the current instance and starts a fresh one.
    
    Usage:
        - Call this method when you want to reset the Ceram application.
    
    Note:
        - Any unsaved state or context will be lost during the restart.
    
    Parameters:
        None
    
    Returns:
        None
    """
  • create_log(self, logtext):

    """
    Log current time and provided text to the text browser.
    
    This method performs the following steps:
    1. Retrieves the current date and time using QDateTime.
    2. Formats the current date and time as a string in the format "%Y-%m-%d %H:%M".
    3. Combines the formatted time with the provided log text.
    4. Appends the combined log entry to the text browser.
    
    Parameters:
        logtext (str): The text to be logged along with the current time.
    
    Returns:
        None. The method updates the Log_textBrowser with the current time and log text.
    """

Gui_GetSet

Inherits: / Is responsible for setting and getting GUI elements and changing the Tabs.

  • tabchange(self, tabobject, index):

    """
    Set the current index of a tab object.
    
    Parameters:
    - tabobject: The tab object.
    - index (int): The index to set for the tab.
    
    Returns:
    None
    """
  • set_label(self, labelobject, labeltext):

    """
    Sets the text of a label object.
    
    Parameters:
    - labelobject: The label object.
    - labeltext (str): The text to set for the label.
    
    Returns:
    None
    """
  • get_lineedit(self, lineeditobject, upper=True):

    """
    Gets the text of a line edit object. Optionally updates the text to be uppercase.
    
    Parameters:
    - lineeditobject: The line edit object.
    - upper (bool): If True, converts the text to uppercase.
    
    Returns:
    str: The text of the line edit object.
    """
  • set_lineedit(self, lineeditobject, input):

    """
    Sets the text of a line edit object.
    
    Parameters:
    - lineeditobject: The line edit object.
    - input (str): The text to set for the line edit.
    
    Returns:
    None
    """
  • upper_lineedit(self, lineeditobject):

    """
    Sets the text of a line edit object to uppercase.
    
    Parameters:
    - lineeditobject: The line edit object.
    
    Returns:
    None
    """
  • get_date(self, dateobject):

    """
    Gets a date from a date time object and splits it into Year, Month, Day.
    
    Parameters:
    - dateobject: The date time object.
    
    Returns:
    Tuple[int, int, int]: Year, Month, Day
    """
  • set_date(self, dateobject, dateinput):

    """
    Sets the date value in the specific date field.
    
    Parameters:
    - dateobject: The date object.
    - dateinput: The date to set.
    
    Returns:
    None
    """
  • encrypt_year(self, encryptyear, startingyear):

    """
    Translates a year to an alphanumeric character.
    
    Parameters:
    - encryptyear (int): The year to be translated.
    - startingyear (int): The starting year for translation.
    
    Returns:
    str: The translated alphanumeric character representing the year.
    """
  • decrypt_year(self, decryptyear, startingyear):

    """
    Translates alphanumeric characters to a year.
    
    Parameters:
    - decryptyear (str): The alphanumeric character representing the year.
    - startingyear (int): The starting year for the translation.
    
    Returns:
    int: The translated year.
    
    Raises:
    TypeError: If the input is not in the correct format.
    """
  • encrypt_month(self, encryptmonth):

    """
    Translates a month to an alphanumeric character.
    
    Parameters:
    - encryptmonth (int): The month to be translated.
    
    Returns:
    str: The translated alphanumeric character representing the month.
    """
  • decrypt_month(self, decryptmonth):

    """
    Translates alphanumeric characters to a month.
    
    Parameters:
    - decryptmonth (str): The alphanumeric character representing the month.
    
    Returns:
    int: The translated month.
    
    Raises:
    TypeError: If the input is not in the correct format.
    """ 
  • encrypt_day(self, encryptday):

    """
    Translates a day to an alphanumeric character.
    
    Parameters:
    - encryptday (int): The day to be translated.
    
    Returns:
    str or int: The translated alphanumeric character or integer representing the day.
    """
  • decrypt_day(self, decryptday):

    """
    Translates alphanumeric characters to a day.
    
    Parameters:
    - decryptday (str or int): The alphanumeric character or integer representing the day.
    
    Returns:
    int: The translated day.
    
    Raises:
    TypeError: If the input is not in the correct format.
    """
  • getstate_checkbox(self, checkboxobject):

    """
    Get the state of a checkbox.
    
    Parameters:
    - checkboxobject: The checkbox object.
    
    Returns:
    bool: True if the checkbox is checked, False otherwise.
    """
  • checkbox_visibilitychange(self, checkboxobject, visibleobject, inverse=False):

    """
    Set the visibility of an object according to the state of a checkbox object.
    
    Parameters:
    - checkboxobject: The checkbox object.
    - visibleobject: The object whose visibility is controlled by the checkbox.
    - inverse (bool): If True, the visibility is set inversely to the checkbox state.
    
    Returns:
    bool: The new visibility state of the object.
    
    Note:
    If inverse is True, the object's visibility will be set to False when the checkbox is checked,
    and vice versa.
    """