[SOLVED] Making a readonly QPlainTextEdit look disabled, using QPalette

  • I tried reading the docs for QPalette but I end up being confused on what actual code I'm supposed to write.

    I have a plain text edit widget, and when I set it to readOnly, I want it to appear disabled (and vice versa). Here's what I tried, and it doesn't work:

    @ void MyPanel::setScriptTextReadOnly(bool isReadOnly) {
    QPalette pal = ui.plainTextEditScript->palette();
    pal.setCurrentColorGroup((isReadOnly ? QPalette::Disabled : QPalette::Active));

    Could anyone advise on what I'm doing wrong?


  • I think you have either of two problems:

    Your style is simply ignoring the palette. That happens with many of the modern desktop styles, as they use the platform API to render the widgets. This is documented in QPalette: [quote]Warning: Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines. This is the case for both the Windows XP, Windows Vista, and the Mac OS X styles.[/quote]

    Your style is setting the color group to use in the palette, not you. So even if you set it to Disabled, your style will just set it back to the group it needs for rendering. If this is the case, the solution is simple: fool your style to by giving it a palette in which you have manually reversed the colors to use for each of the roles.

  • OK, I think I understand the second problem - it makes a lot of sense - but not the solution. What setter should I be using to change the disabled group's colors to the active one's, for example?

  • Just create your own palette, doing something like this:
    void setupPalette()
    QPalette palette(widget->palette());
    QPalette newPalette(palette);

    copyPaletteColorGroup(palette, QPalette::Inactive, newPalette, QPalette::Disabled);
    copyPaletteColorGroup(palette, QPalette::Disabled, newPalette, QPalette::Inactive);

    // Copies all brushes in a color group from one palette to another
    void copyPaletteColorGroup(const QPalette& srcPalette, QPalette::ColorGroup srcGroup, QPalette& targetPalette, QPalette::ColorGroup targetGroup)
    for (int i(QPalette::WindowText); i < QPalette::ToolTipText; ++i) { //WindowText = 0, ToolTipText = 19; one could skip 17
    QPalette::ColorRole role = static_castQPalette::ColorRole(i);
    targetPalette.setBrush(targetGroup, role, srcPalette.brush(srcGroup, role));

    (code above is just to get the idea: it is completely untested and typed directly in the forum editor)

  • Thanks, you put me on the right path.

    For the record, here's what I ended up needing:

    @textEditPaletteNormal = ui.plainTextEditScript->palette();
    textEditPaletteReadOnly = ui.plainTextEditScript->palette();
    textEditPaletteReadOnly.setColor(QPalette::Active, QPalette::Base, textEditPaletteNormal.color(QPalette::Disabled, QPalette::Base));
    textEditPaletteReadOnly.setColor(QPalette::Inactive, QPalette::Base, textEditPaletteNormal.color(QPalette::Disabled, QPalette::Base));@

    I store these two palettes and then apply them as needed.

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.