Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Why do SpinBox and TextField look so bad on Windows?

Why do SpinBox and TextField look so bad on Windows?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 2 Posters 305 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Magicrafter13
    wrote on last edited by
    #1

    I have this snippet of QML:

    import QtQuick
    import QtQuick.Window
    import QtQuick.Controls 6.3
    
    ...
    
                    Item {
                        id: date_boxes
                        height: year_number.height
                        width: day_label.x + day_label.width - year_number.x
                        anchors.horizontalCenter: parent.horizontalCenter
    
                        SpinBox {
                            id: year_number
                            width: 52
                            editable: true
                            wheelEnabled: true
                            to: 2023
                            from: 2019
                            value: manager.year
                            anchors.left: parent.left
                            activeFocusOnTab: true
    
                            onValueChanged: manager.year = value
    
                            textFromValue: function(value) {
                                return value;
                            }
                        }
    
                        Text {
                            id: year_label
                            color: pal.text
                            text: qsTr("Year (YYYY)")
                            anchors.verticalCenter: year_number.verticalCenter
                            anchors.left: year_number.right
                            font.pixelSize: 12
                            anchors.leftMargin: 10
                        }
    
                        SpinBox {
                            id: month_number
                            width: 37
                            anchors.verticalCenter: year_label.verticalCenter
                            anchors.left: year_label.right
                            wheelEnabled: true
                            editable: true
                            to: 12
                            from: 1
                            value: manager.month
                            activeFocusOnTab: true
                            anchors.leftMargin: 20
    
                            onValueChanged: manager.month = value
                        }
    
                        Text {
                            id: month_label
                            color: pal.text
                            text: qsTr("Month (MM)")
                            anchors.verticalCenter: month_number.verticalCenter
                            anchors.left: month_number.right
                            font.pixelSize: 12
                            anchors.leftMargin: 10
                        }
    
                        SpinBox {
                            id: day_number
                            width: 37
                            anchors.verticalCenter: month_label.verticalCenter
                            anchors.left: month_label.right
                            wheelEnabled: true
                            editable: true
                            to:
                                (month_number.value === 4 || month_number.value === 6 || month_number.value ===  9 || month_number.value === 11)
                                    ? 30
                                    : month_number.value === 2
                                        ? (year_number.value % 4 == 0 ? 29 : 28)
                                        : 31
                            from: 1
                            value: manager.day
                            activeFocusOnTab: true
                            anchors.leftMargin: 20
    
                            onValueChanged: manager.day = value
                        }
    
                        Text {
                            id: day_label
                            color: pal.text
                            text: qsTr("Day (DD)")
                            anchors.verticalCenter: day_number.verticalCenter
                            anchors.left: day_number.right
                            font.pixelSize: 12
                            anchors.leftMargin: 10
                        }
    
    
    
                    }
    
                    Text {
                        id: title_label
                        color: pal.text
                        text: qsTr("Sermon Title")
                        font.pixelSize: 12
                    }
    
                    TextField {
                        id: title
                        color: pal.text
                        anchors.left: parent.left
                        anchors.right: parent.right
                        font.pixelSize: 12
                        placeholderText: "Authority in the Church"
                        activeFocusOnTab: true
                        topPadding: 4
                        bottomPadding: 4
                        leftPadding: 10
                        rightPadding: 10
    
                        onTextChanged: manager.updateTitle(title.text)
                    }
    

    Here's how it looks under KDE Plasma:
    bfe86af6-56a6-47c1-9b76-5fbaa5a2a985-image.png
    And here's how it looks under Windows 10:
    8d0fcf3d-fb21-49a5-be37-2fbc2af269c5-image.png

    In Plasma it looks... well normal, but in Windows the text boxes are reduced to corners instead of full rectangles, and those corner pieces even go over the text! (Since my date boxes are rather small.)

    Is this just how these particular UI elements work in Windows or is there something here I need to fix?

    mzimmersM 1 Reply Last reply
    1
    • M Magicrafter13

      I have this snippet of QML:

      import QtQuick
      import QtQuick.Window
      import QtQuick.Controls 6.3
      
      ...
      
                      Item {
                          id: date_boxes
                          height: year_number.height
                          width: day_label.x + day_label.width - year_number.x
                          anchors.horizontalCenter: parent.horizontalCenter
      
                          SpinBox {
                              id: year_number
                              width: 52
                              editable: true
                              wheelEnabled: true
                              to: 2023
                              from: 2019
                              value: manager.year
                              anchors.left: parent.left
                              activeFocusOnTab: true
      
                              onValueChanged: manager.year = value
      
                              textFromValue: function(value) {
                                  return value;
                              }
                          }
      
                          Text {
                              id: year_label
                              color: pal.text
                              text: qsTr("Year (YYYY)")
                              anchors.verticalCenter: year_number.verticalCenter
                              anchors.left: year_number.right
                              font.pixelSize: 12
                              anchors.leftMargin: 10
                          }
      
                          SpinBox {
                              id: month_number
                              width: 37
                              anchors.verticalCenter: year_label.verticalCenter
                              anchors.left: year_label.right
                              wheelEnabled: true
                              editable: true
                              to: 12
                              from: 1
                              value: manager.month
                              activeFocusOnTab: true
                              anchors.leftMargin: 20
      
                              onValueChanged: manager.month = value
                          }
      
                          Text {
                              id: month_label
                              color: pal.text
                              text: qsTr("Month (MM)")
                              anchors.verticalCenter: month_number.verticalCenter
                              anchors.left: month_number.right
                              font.pixelSize: 12
                              anchors.leftMargin: 10
                          }
      
                          SpinBox {
                              id: day_number
                              width: 37
                              anchors.verticalCenter: month_label.verticalCenter
                              anchors.left: month_label.right
                              wheelEnabled: true
                              editable: true
                              to:
                                  (month_number.value === 4 || month_number.value === 6 || month_number.value ===  9 || month_number.value === 11)
                                      ? 30
                                      : month_number.value === 2
                                          ? (year_number.value % 4 == 0 ? 29 : 28)
                                          : 31
                              from: 1
                              value: manager.day
                              activeFocusOnTab: true
                              anchors.leftMargin: 20
      
                              onValueChanged: manager.day = value
                          }
      
                          Text {
                              id: day_label
                              color: pal.text
                              text: qsTr("Day (DD)")
                              anchors.verticalCenter: day_number.verticalCenter
                              anchors.left: day_number.right
                              font.pixelSize: 12
                              anchors.leftMargin: 10
                          }
      
      
      
                      }
      
                      Text {
                          id: title_label
                          color: pal.text
                          text: qsTr("Sermon Title")
                          font.pixelSize: 12
                      }
      
                      TextField {
                          id: title
                          color: pal.text
                          anchors.left: parent.left
                          anchors.right: parent.right
                          font.pixelSize: 12
                          placeholderText: "Authority in the Church"
                          activeFocusOnTab: true
                          topPadding: 4
                          bottomPadding: 4
                          leftPadding: 10
                          rightPadding: 10
      
                          onTextChanged: manager.updateTitle(title.text)
                      }
      

      Here's how it looks under KDE Plasma:
      bfe86af6-56a6-47c1-9b76-5fbaa5a2a985-image.png
      And here's how it looks under Windows 10:
      8d0fcf3d-fb21-49a5-be37-2fbc2af269c5-image.png

      In Plasma it looks... well normal, but in Windows the text boxes are reduced to corners instead of full rectangles, and those corner pieces even go over the text! (Since my date boxes are rather small.)

      Is this just how these particular UI elements work in Windows or is there something here I need to fix?

      mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #2

      @Magicrafter13 this won't fix all your problems, but...I recreated your QML code using layouts (I had to remove a few references to objects that you didn't include.) Look this over:

      import QtQuick
      import QtQuick.Controls
      import QtQuick.Layouts
      
      ApplicationWindow {
          id: mainWindow
      
          visible: true
          width: 640
          height: 480
      
          ColumnLayout {
              height: mainWindow.height
              width: mainWindow.width
              RowLayout {
                  id: date_boxes
                  height: year_number.height
                  Layout.fillWidth: true
                  SpinBox {
                      id: year_number
                      editable: true
                      wheelEnabled: true
                      to: 2023
                      from: 2019
                      activeFocusOnTab: true
                      textFromValue: function(value) {
                          return value;
                      }
                  }
                  Text {
                      id: year_label
                      text: qsTr("Year (YYYY)")
                      font.pixelSize: 12
                      anchors.leftMargin: 10
                  }
      
                  SpinBox {
                      id: month_number
                      wheelEnabled: true
                      editable: true
                      to: 12
                      from: 1
                      activeFocusOnTab: true
                      anchors.leftMargin: 20
                  }
      
                  Text {
                      id: month_label
                      text: qsTr("Month (MM)")
                      font.pixelSize: 12
                  }
      
                  SpinBox {
                      id: day_number
                      wheelEnabled: true
                      editable: true
                      to:
                          (month_number.value === 4 || month_number.value === 6 || month_number.value ===  9 || month_number.value === 11)
                          ? 30
                          : month_number.value === 2
                            ? (year_number.value % 4 == 0 ? 29 : 28)
                            : 31
                      from: 1
                      activeFocusOnTab: true
      
                  }
      
                  Text {
                      id: day_label
                      text: qsTr("Day (DD)")
                      font.pixelSize: 12
                  }
              }
      
              Text {
                  id: title_label
                  text: qsTr("Sermon Title")
                  font.pixelSize: 12
              }
      
              TextField {
                  id: title
                  Layout.fillWidth: true
                  Layout.fillHeight: true
                  font.pixelSize: 12
                  placeholderText: "Authority in the Church"
                  activeFocusOnTab: true
                  topPadding: 4
                  bottomPadding: 4
                  leftPadding: 10
                  rightPadding: 10
              }
          }
      }
      

      Another part of the problem might be the style you're using. The default Windows style isn't all that great, on a number of fronts. You can change it to plasma if you want, with the QQuickStyle::setStyle() function in your main.cpp.

      M 1 Reply Last reply
      0
      • mzimmersM mzimmers

        @Magicrafter13 this won't fix all your problems, but...I recreated your QML code using layouts (I had to remove a few references to objects that you didn't include.) Look this over:

        import QtQuick
        import QtQuick.Controls
        import QtQuick.Layouts
        
        ApplicationWindow {
            id: mainWindow
        
            visible: true
            width: 640
            height: 480
        
            ColumnLayout {
                height: mainWindow.height
                width: mainWindow.width
                RowLayout {
                    id: date_boxes
                    height: year_number.height
                    Layout.fillWidth: true
                    SpinBox {
                        id: year_number
                        editable: true
                        wheelEnabled: true
                        to: 2023
                        from: 2019
                        activeFocusOnTab: true
                        textFromValue: function(value) {
                            return value;
                        }
                    }
                    Text {
                        id: year_label
                        text: qsTr("Year (YYYY)")
                        font.pixelSize: 12
                        anchors.leftMargin: 10
                    }
        
                    SpinBox {
                        id: month_number
                        wheelEnabled: true
                        editable: true
                        to: 12
                        from: 1
                        activeFocusOnTab: true
                        anchors.leftMargin: 20
                    }
        
                    Text {
                        id: month_label
                        text: qsTr("Month (MM)")
                        font.pixelSize: 12
                    }
        
                    SpinBox {
                        id: day_number
                        wheelEnabled: true
                        editable: true
                        to:
                            (month_number.value === 4 || month_number.value === 6 || month_number.value ===  9 || month_number.value === 11)
                            ? 30
                            : month_number.value === 2
                              ? (year_number.value % 4 == 0 ? 29 : 28)
                              : 31
                        from: 1
                        activeFocusOnTab: true
        
                    }
        
                    Text {
                        id: day_label
                        text: qsTr("Day (DD)")
                        font.pixelSize: 12
                    }
                }
        
                Text {
                    id: title_label
                    text: qsTr("Sermon Title")
                    font.pixelSize: 12
                }
        
                TextField {
                    id: title
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    font.pixelSize: 12
                    placeholderText: "Authority in the Church"
                    activeFocusOnTab: true
                    topPadding: 4
                    bottomPadding: 4
                    leftPadding: 10
                    rightPadding: 10
                }
            }
        }
        

        Another part of the problem might be the style you're using. The default Windows style isn't all that great, on a number of fronts. You can change it to plasma if you want, with the QQuickStyle::setStyle() function in your main.cpp.

        M Offline
        M Offline
        Magicrafter13
        wrote on last edited by
        #3

        @mzimmers I added 2 (3) lines to main (I'm doing this in Python not C++):

        if __name__ == "__main__":
        	# Set the application style to KDE Plasma
        	settings = QSettings("org/kde/desktop", "applications")
        	settings.setValue("style", "org.kde.desktop")
        
        	app = QApplication(sys.argv)
        	manager = Manager()
        	engine = QQmlApplicationEngine()
        	engine.rootContext().setContextProperty("manager", manager)
        	qml_file = str(Path(__file__).resolve().parent / "main.qml")
        	engine.load(qml_file)
        	if not engine.rootObjects():
        		sys.exit(-1)
        
        	# ...
        
        	# Start program
        	sys.exit(app.exec())
        

        However this did not change the styling at all. I did discover the -style command line option, but on Windows there were only 3 style available. Fusion actually looks pretty nice and fixes all my issues, however it doesn't respect the system dark/light mode setting and is always dark (which to be fair looks superior but it would be nice if it matched the system colors).

        Do I have to install some package to get additional styles?

        Actually right before submitting this reply I realized Fusion is KDE Plasma because I tried it on my Linux install.

        So now there are only really 3 issues:

        • Fusion on Windows and macOS forces dark theme
        • Fusion on Windows and macOS makes the radio buttons blue for some reason (looks strange but not a deal breaker, I can live with this)
        • How can I make it always use this theme, when creating a package with pyinstaller

        I kinda have a solution to my last problem there, I can just hard code the QApplication call to use ["-style", "Fusion"] instead of sys.argv, since there doesn't seem to be a way to build it into the PyInstaller build, even if this solution seems a little cursed haha.

        Either way, thanks for pointing me in the direction of the application Styling.

        mzimmersM 1 Reply Last reply
        0
        • M Magicrafter13

          @mzimmers I added 2 (3) lines to main (I'm doing this in Python not C++):

          if __name__ == "__main__":
          	# Set the application style to KDE Plasma
          	settings = QSettings("org/kde/desktop", "applications")
          	settings.setValue("style", "org.kde.desktop")
          
          	app = QApplication(sys.argv)
          	manager = Manager()
          	engine = QQmlApplicationEngine()
          	engine.rootContext().setContextProperty("manager", manager)
          	qml_file = str(Path(__file__).resolve().parent / "main.qml")
          	engine.load(qml_file)
          	if not engine.rootObjects():
          		sys.exit(-1)
          
          	# ...
          
          	# Start program
          	sys.exit(app.exec())
          

          However this did not change the styling at all. I did discover the -style command line option, but on Windows there were only 3 style available. Fusion actually looks pretty nice and fixes all my issues, however it doesn't respect the system dark/light mode setting and is always dark (which to be fair looks superior but it would be nice if it matched the system colors).

          Do I have to install some package to get additional styles?

          Actually right before submitting this reply I realized Fusion is KDE Plasma because I tried it on my Linux install.

          So now there are only really 3 issues:

          • Fusion on Windows and macOS forces dark theme
          • Fusion on Windows and macOS makes the radio buttons blue for some reason (looks strange but not a deal breaker, I can live with this)
          • How can I make it always use this theme, when creating a package with pyinstaller

          I kinda have a solution to my last problem there, I can just hard code the QApplication call to use ["-style", "Fusion"] instead of sys.argv, since there doesn't seem to be a way to build it into the PyInstaller build, even if this solution seems a little cursed haha.

          Either way, thanks for pointing me in the direction of the application Styling.

          mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #4

          @Magicrafter13 said in Why do SpinBox and TextField look so bad on Windows?:

          Do I have to install some package to get additional styles?

          You shouldn't (I'm fairly sure I didn't), but in your QML you may need to import the controls for the style you selected:

          import qtQuick.Controls.Material // or whatever
          

          Also, take a look at this bug report

          If you're on a relatively new release of Qt, this should solve your light/dark issue.

          1 Reply Last reply
          0
          • M Magicrafter13 has marked this topic as solved on

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved