Multi page report with QTextDocument - qt

I am generating html report with QTextDocument, my problem it comes when it should print each table on its own page, but it doesn't. I tried to use QPainter along with QTextDocument::drawContents() but this makes it show only the first page.
Another attempt was to insert a div and set its style to page-break-after:auto even it is supported by QTextDocument web engine, but this didn't work too.
void SemesterResultsReport::printDivisionStudentsNotes() {
QMap<int, int> divisionsList = SemesterResultsReport::getSelectedDivisions();
QPrinter *printer = new QPrinter(QPrinter::ScreenResolution);
printer->setFullPage(true);
printer->setResolution(90);
printer->setPaperSize(QPrinter::A4);
printer->setOrientation(QPrinter::Landscape);
printer->setPageMargins(5, 5, 5, 5, QPrinter::Millimeter);
/*printer->setOutputFormat(QPrinter::PdfFormat);
printer->setOutputFileName("sdf.pdf");*/
QPrintPreviewDialog *dlg = new QPrintPreviewDialog(printer, this);
connect(dlg, SIGNAL(paintRequested(QPrinter *)), this, SLOT(printOrder(QPrinter *)));
dlg->exec();
}
void SemesterResultsReport::printOrder(QPrinter *printer) {
QString strStream;
QTextStream out(&strStream);
QSqlQuery studentInfo, studentNotes;
QSqlRecord studentInfoRec, studentNotesRec;
QMap<int, int> selectedDivisions = SemesterResultsReport::getSelectedDivisions();
QMap<int, int>::const_iterator divisionId;
QTextDocument *document = new QTextDocument();
QTextCursor cursor(document);
QTextOption options;
options.setTextDirection(Qt::RightToLeft);
QSizeF paperSize;
paperSize.setWidth(printer->width());
paperSize.setHeight(printer->height());
document->setDefaultTextOption(options);
document->setPageSize(paperSize);
int mat_div = 0;
int level = 0;
int semester = ui.semestersList->currentText().toInt();
int school_year = 2015;
int numMaterials = 0;
// Report
out << "<!DOCTYPE html>"
<< "<html>\n"
<< "<head>"
<< "<title>ff</title>"
<< "<meta http-equiv=\"Content-Type\" content =\"text/html;charset=utf-8\" >"
<< "<style type=\"text/css\"> "
<< " html, body { margin: 5px; direction: rtl; width: 100% !important; align: right !important; float: right !important; }"
<< " *, p { font-family: \"Times New Roman\"; font-size: 16px; }"
<< " img { display: block; margin: 0 auto; }"
<< " p.title { font-weight: bold; font-size: 22px; align: center !important; }"
<< " table { border: 1; border-collapse: collapse; page-break-after:auto !important; width: 100% !important; align: right !important; float: right !important; }"
<< " th, td { border: 1px solid #000; padding: 0; align: center; page-break-inside:avoid; page-break-after:auto; }"
<< " tr { page-break-inside:avoid; page-break-after:auto !important; }"
<< " thead { display:table-header-group; }"
<< " tfoot { display:table-footer-group; }"
<< " .pagebreak { page-break-after:auto !important; } "
<< "</style>"
<< "</head>"
<< "<body>";
for (divisionId = selectedDivisions.constBegin(); divisionId != selectedDivisions.constEnd(); ++divisionId) {
mat_div = divisionId.key();
level = divisionId.value();
numMaterials = 0;
// Report header, get division materials to set as header
QStringList divisionMaterialsNames = SemesterResultsReport::getDivisionMaterialsNames(mat_div, level, school_year);
out << "<table float=\"right\" border=1 cellspacing=0 cellpadding=2>";
numMaterials = divisionMaterialsNames.size();
out << "<thead><tr bgcolor=#f0f0f0>";
for (int i = numMaterials - 1; i > -1; --i) {
out << "<th>" + divisionMaterialsNames[i] + "</th>";
}
out << "<th>" + QString("الإسم") + "</th>"
<< "<th>" + QString("اللقب") + "</th>"
<< "<th>" + QString("الرقم التسلسلي") + "</th>"
<< "</tr></thead>";
// Echo student info plus materials notes
QString fullName = ", fname, lname";
QString infoQuery = "SELECT Student.mat_stud as matStud" + fullName + " FROM Student, Class, Division WHERE Class.mat_div = Division.mat_div AND Class.mat_class = Student.mat_class AND school_year = " + QString::number(school_year) + " AND Class.level = " + QString::number(level) + " AND Division.mat_div = " + QString::number(mat_div);
studentInfo.exec(infoQuery);
studentInfoRec = studentInfo.record();
fullName.clear();
infoQuery = "SELECT Student.mat_stud as matStud FROM Student, Class, Division WHERE Class.mat_div = Division.mat_div AND Class.mat_class = Student.mat_class AND school_year = " + QString::number(school_year) + " AND Class.level = " + QString::number(level) + " AND Division.mat_div = " + QString::number(mat_div);
QString notesQuery = "SELECT materials_notes FROM Notes WHERE mat_stud IN (" + infoQuery + ") AND school_year = " + QString::number(school_year) + " AND level = " + QString::number(level) + " AND mat_div = " + QString::number(mat_div) + " AND semester = " + QString::number(semester);
studentNotes.exec(notesQuery);
studentNotesRec = studentNotes.record();
QStringList studentNotesList;
while (studentInfo.next()) {
out << "<tr>";
studentNotes.next();
studentNotesList = studentNotes.value(studentNotesRec.indexOf("materials_notes")).toString().split(",");
for (int i = 0; i < numMaterials; ++i) {
out << "<th>" + studentNotesList[i] + "</th>";
}
out << " <th>" + studentInfo.value(studentInfoRec.indexOf("lname")).toString() + "</th>"
<< " <th>" + studentInfo.value(studentInfoRec.indexOf("fname")).toString() + "</th>"
<< " <th>" + studentInfo.value(studentInfoRec.indexOf("matStud")).toString() + "</th>";
out << "</tr>";
}
// Close table tag, and insert new page, but it doesn't work
out << "</table><div style=\"page-break-after:auto !important;\"></div>";
}
// Finish report
out << "</body>"
<< "</html>";
/*
* Prepare QTextDocument
*/
document->setHtml(strStream);
document->print(printer);
// this makes only the first page printed
/*QPainter painter;
painter.begin(printer);
document->drawContents(&painter, printer->pageRect());
painter.end();*/
}

Related

How to send max30100 sensor data repeatedly to google firebase

sorry I ask a lot of questions in this forum because I am really a beginner. So I have a body temperature and oxygen saturation monitoring tool project. I'm using nodemcu esp8266, sensor ds18b20, and sensor max30100. the configuration between the three tools has been successful, but when entering a coding program to send data to google firebase the oxygen saturation value cannot retrieve data repeatedly, for example as shown below. enter image description here
This my code :
//ESP8266 Based Patient Health Monitoring System
#include <ESP8266WebServer.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <OneWire.h>
#include <DallasTemperature.h>
#include <FirebaseArduino.h>
#define FIREBASE_HOST "monitoring-oximeter-d2ff2-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "uxoi7mv66IxOBG5ZoGBJY51hPp0AfbYezmmeCkvu"
#define DS18B20 2 //D4 pin= GPIO pin 2
#define REPORTING_PERIOD_MS 1000
int BPM, SpO2, bodytemperature;
/*Put your SSID & Password*/
const char* ssid = "HAURA"; // Enter SSID here
const char* password = "13131313"; //Enter Password here
PulseOximeter pox;
uint32_t tsLastReport = 0;
OneWire oneWire(DS18B20);
DallasTemperature sensors(&oneWire);
ESP8266WebServer server(80);
int g;
//-----------------
void onBeatDetected()
{
;
}
void setup() {
lcd.begin(16,2);
lcd.init();
lcd.backlight();
lcd.clear();
lcd.print("Digital Oximeter");
lcd.setCursor(0, 1);
lcd.print("Tunggu Koneksi..");
delay(1000);
if (!pox.begin()) {
lcd.setCursor(0, 1);
lcd.print("Koneksi Gagal ");
for(;;);
} else {
;
}
pox.setIRLedCurrent(MAX30100_LED_CURR_24MA);
pox.setOnBeatDetectedCallback(onBeatDetected);
lcd.clear();
lcd.print("SpO2= %");
lcd.setCursor(0, 1);
lcd.print("PR = BPM");
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Serial.begin(115200);
pinMode(16, OUTPUT);
delay(100);
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
Serial.print("Initializing pulse oximeter..");
if (!pox.begin()) {
Serial.println("FAILED");
for (;;);
} else {
Serial.println("SUCCESS");
}
}
void loop() {
server.handleClient();
pox.update();
sensors.requestTemperatures();
g++;
if(g>5000){
g=0;
BPM = pox.getHeartRate();
SpO2 = pox.getSpO2();
bodytemperature = sensors.getTempCByIndex(0);
if((BPM<101)&&(SpO2<101)&&(bodytemperature<101)){
lcd.setCursor(5, 0);
lcd.print(SpO2);
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.print(BPM);
lcd.print(" ");
}
}
Firebase.setInt("BPM", BPM);
if (Firebase.failed()) {
Serial.print("pushing /logs failed:");
Serial.println(Firebase.error());
return;
}
Firebase.setInt("SpO2", SpO2);
if (Firebase.failed()) {
Serial.print("pushing /logs failed:");
Serial.println(Firebase.error());
return;
}
Firebase.setInt("bodytemperature", bodytemperature);
if (Firebase.failed()) {
Serial.print("pushing /logs failed:");
Serial.println(Firebase.error());
return;
}
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
bodytemperature = sensors.getTempCByIndex(0);
BPM = pox.getHeartRate();
SpO2 = pox.getSpO2();
Serial.print("BPM: ");
Serial.println(BPM);
Serial.print("SpO2: ");
Serial.print(SpO2);
Serial.println("%");
Serial.print("Body Temperature: ");
Serial.print(bodytemperature);
Serial.println("°C");
Serial.println("*********************************");
Serial.println();
tsLastReport = millis();
}
}
void handle_OnConnect() {
server.send(200, "text/html", SendHTML(BPM, SpO2, bodytemperature));
}
void handle_NotFound() {
server.send(404, "text/plain", "Not found");
}
String SendHTML(float BPM, float SpO2, float bodytemperature) {
String html = "<!DOCTYPE html>";
html += "<html>";
html += "<head>";
html += "<title>Patient Health Monitoring</title>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.7.2/css/all.min.css'>";
html += "<link rel='stylesheet' type='text/css' href='styles.css'>";
html += "<style>";
html += "body { background-color: #fff; font-family: sans-serif; color: #333333; font: 14px Helvetica, sans-serif box-sizing: border-box;}";
html += "#page { margin: 20px; background-color: #fff;}";
html += ".container { height: inherit; padding-bottom: 20px;}";
html += ".header { padding: 20px;}";
html += ".header h1 { padding-bottom: 0.3em; color: #008080; font-size: 45px; font-weight: bold; font-family: Garmond, 'sans-serif'; text-align: center;}";
html += "h2 { padding-bottom: 0.2em; border-bottom: 1px solid #eee; margin: 2px; text-align: left;}";
html += ".header h3 { font-weight: bold; font-family: Arial, 'sans-serif'; font-size: 17px; color: #b6b6b6; text-align: center;}";
html += ".box-full { padding: 20px; border 1px solid #ddd; border-radius: 1em 1em 1em 1em; box-shadow: 1px 7px 7px 1px rgba(0,0,0,0.4); background: #fff; margin: 20px; width: 300px;}";
html += "#media (max-width: 494px) { #page { width: inherit; margin: 5px auto; } #content { padding: 1px;} .box-full { margin: 8px 8px 12px 8px; padding: 10px; width: inherit;; float: none; } }";
html += "#media (min-width: 494px) and (max-width: 980px) { #page { width: 465px; margin 0 auto; } .box-full { width: 380px; } }";
html += "#media (min-width: 980px) { #page { width: 930px; margin: auto; } }";
html += ".sensor { margin: 12px 0px; font-size: 2.5rem;}";
html += ".sensor-labels { font-size: 1rem; vertical-align: middle; padding-bottom: 15px;}";
html += ".units { font-size: 1.2rem;}";
html += "hr { height: 1px; color: #eee; background-color: #eee; border: none;}";
html += "</style>";
//Ajax Code Start
html += "<script>\n";
html += "setInterval(loadDoc,1000);\n";
html += "function loadDoc() {\n";
html += "var xhttp = new XMLHttpRequest();\n";
html += "xhttp.onreadystatechange = function() {\n";
html += "if (this.readyState == 4 && this.status == 200) {\n";
html += "document.body.innerHTML =this.responseText}\n";
html += "};\n";
html += "xhttp.open(\"GET\", \"/\", true);\n";
html += "xhttp.send();\n";
html += "}\n";
html += "</script>\n";
//Ajax Code END
html += "</head>";
html += "<body>";
html += "<div id='page'>";
html += "<div class='header'>";
html += "<h1>Health Monitoring System</h1>";
html += "</div>";
html += "<div id='content' align='center'>";
html += "<div class='box-full' align='left'>";
html += "<h2>Sensors Readings</h2>";
html += "<div class='sensors-container'>";
//For Heart Rate
html += "<p class='sensor'>";
html += "<i class='fas fa-heartbeat' style='color:#cc3300'></i>";
html += "<span class='sensor-labels'> Heart Rate </span>";
html += (int)BPM;
html += "<sup class='units'>BPM</sup>";
html += "</p>";
html += "<hr>";
//For Sp02
html += "<p class='sensor'>";
html += "<i class='fas fa-burn' style='color:#f7347a'></i>";
html += "<span class='sensor-labels'> Sp02 </span>";
html += (int)SpO2;
html += "<sup class='units'>%</sup>";
html += "</p>";
html += "<hr>";
//For Body Temperature
html += "<p class='sensor'>";
html += "<i class='fas fa-thermometer-full' style='color:#d9534f'></i>";
html += "<span class='sensor-labels'> Body Temperature </span>";
html += (int)bodytemperature;
html += "<sup class='units'>°C</sup>";
html += "</p>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "</div>";
html += "</body>";
html += "</html>";
return html;
}

Qt Print QStandardItemModel

I want to print rows of "QStandardItemModel". I use this code, It works but table is not beautiful.
I don't know how to adjust row height and I don't know how to set column widths based on the width of cells in the first row of the table.
QPrinter printer;
printer.setPageSize(QPrinter::A4);
printer.setFullPage(true);
QPrintDialog *dlg = new QPrintDialog(&printer,0);
if(dlg->exec() == QDialog::Accepted) {
QPainter painter;
if (painter.begin(&printer)) {
painter.translate(0,0);
int position = 0;
int rowCount=newMyModel->rowCount(QModelIndex());
for(int r=0;r<rowCount;r++)
{
if( position > painter.window().height()-100 )
{
printer.newPage();
position = 0;
painter.resetTransform();
painter.translate(0, 0);
}
QString html="<table style='page-break-after:always' border='1' width='100%' cellpadding =10 style='border-width: 1px;border-style: solid;border-color: #9e9e9e;width:100%'>";
index=newMyModel->index(r, 0);
QVariant prop1=index.data(MyModel::prop1);
QVariant prop2=index.data(MyModel::prop2);
'''
'''
'''
html.append(
"<tr style='background-color:red'>"
"<td style='border-width: 1px;padding:10; border-style: solid; border-color: #9e9e9e;width:16%'>"+prop1.toString()+" </td>"
"<td style='border-width: 1px;padding:10; border-style: solid; border-color: #9e9e9e;width:16%'>"+prop2.toString()+" </td>"
...
...
...);
}
html.append("</table>");
QRect rect = painter.boundingRect(painter.window(),
Qt::AlignJustify | Qt::TextWordWrap,
html);
QTextDocument doc;
doc.setHtml(html);
doc.drawContents(&painter, rect);
painter.drawRect(rect);
painter.translate(0, rect.height());
position += rect.height();
}
painter.end();
}
}

CSS How to align checkbox image

I trying to style my checkbox with custom image, but what I have tried so far is the tick image stick with the text, this doesn't look good, how to make the tick image and text align nicely ?
JS Fiddle
What I want it look like this ✔ mango
CSS
.label{
margin:5px;
color: #ccc;
font-size:12px;
cursor:pointer;
}
.label:hover{
color:#444;
}
input[type=checkbox]{
display:none;
}
input[type=checkbox] + .label {
padding:5px;
}
input[type=checkbox]:checked + .label {
color: #444;
position:relative;
margin:2px;
background-image:url(http://icons.iconarchive.com/icons/custom-icon-design/mini/16/Accept-icon.png);
background-repeat:no-repeat;
background-color:#ccc;
}
Note: From a usability point of view:
when only a single option should be selected, use radio buttons and not ticks.
currently you have to click the label twice to make a different selection; clicking on another option should deselect a previously checked option.
Use padding for the left of the label. In this example, padding-left: 10px
Position the background images x and y position. In this example I have placed it all in the background property:
background: url(urlPath) 10px center no-repeat
That gives us this:
Example
var PG = {
divid: "",
multiselection: "",
optionitem: [],
init: function(divid, multiselection, optionitem) {
PG.divid = divid;
PG.multiselect = multiselection;
PG.optionitem = optionitem;
},
test: function() {
for (var i = 0; PG.optionitem.length > i; i++) {
alert(PG.optionitem[i].name);
}
},
render_1: function() {
$.each(array, function(i, obj) {
var selection = "<input class='the_checkbox' type='checkbox' id=" + obj.value + " name=" + obj.name + " value=" + obj.value + ">" +
"<label class='label' for=" + obj.value + ">" + obj.value + "</label>" +
"<div class='pbar'><div class='pbarinner' style='width:75%;'></div></div>";
$("#" + PG.divid).append(selection);
if ($('input#' + obj.value).is(':checked')) {
$('.pbar').css('display', 'block');
}
});
$("#survey_title").append("What is your favorite fruit??");
$("#choose").append("Please select 1 fruit only:");
$('.the_checkbox').on('change', function(evt) {
if ($(this).siblings(':checked').length >= PG.multiselect) {
this.checked = false;
}
});
},
render_2: function() {
$.each(w_array, function(i, obj) {
var selection = "<input class='the_checkbox' type='checkbox' id=" + obj.value + " name=" + obj.name + " value=" + obj.value + ">" +
"<label class='label' for=" + obj.value + ">" + obj.value + "</label>";
$("#" + PG.divid).append(selection);
});
$("#survey_title").append("item??");
$("#choose").append("Please select 3 item :");
$('.the_checkbox').on('change', function(evt) {
if ($(this).siblings(':checked').length >= PG.multiselect) {
this.checked = false;
}
});
},
save: function() {}
}
var array = [];
array[0] = {
"name": "fruit",
"value": "mango"
};
array[1] = {
"name": "fruit",
"value": "apple"
};
array[2] = {
"name": "fruit",
"value": "orange"
};
array[3] = {
"name": "fruit",
"value": "banana"
};
var w_array = [];
w_array[0] = {
"name": "com",
"value": "RAM"
};
w_array[1] = {
"name": "com",
"value": "DISK"
};
w_array[2] = {
"name": "com",
"value": "BOOK"
};
w_array[3] = {
"name": "com",
"value": "PEN"
};
PG.init("popupfoot", "1", array);
PG.render_1();
/*PG.init("survey_question", "3", w_array);
PG.render_2();*/
.label {
margin: 5px;
color: #ccc;
font-size: 12px;
cursor: pointer;
}
.label:hover {
color: #444;
}
input[type=checkbox] {
display: none;
}
input[type=checkbox] + .label {
padding: 5px;
}
input[type=checkbox]:checked + .label {
color: #444;
position: relative;
margin: 2px;
background: url(http://icons.iconarchive.com/icons/custom-icon-design/mini/16/Accept-icon.png) 10px center no-repeat;
background-color: #ccc;
padding-left: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="popupfoot">
<p id="survey_title"></p>
<h5 id="choose"></h5>
<div id="survey_question"></div>
</div>
Try using the background position property
For e.g.
In your case
background-position: center left;
I've modified the padding left too. Here is the fiddle.
http://jsfiddle.net/8190zjvf/9/
Here I have changed padding-left of the list to 20 px;
And to place the tick in the left I've used the background-position property. Hope it is clear.

How to disable weekends in the ajax calender extender?

I have implemented the following code: this function not call
My Html Code is:
<asp:CalendarExtender ID="CalendarExtender1" runat="server" Format="dd/MM/yy" PopupButtonID="ImageButton1" PopupPosition="BottomRight" Enabled="true" OnClientDateSelectionChanged="DisableWeekends" TargetControlID="txtStartDate">
onclientshown=`"DisableWeekends"
The function is give below:
function DisableWeekends(sender, args) {
for (var i = 0; i < sender._days.all.length; i++) {
for (var j = 0; j < 6; j++) {
if (sender._days.all[i].id == "DisabledWeekendsCalendar" + j + "_5") {
sender._days.all[i].disabled = true;
sender._days.all[i].innerHTML =
"<div>" + sender._days.all[i].innerText + "</div>";
}
if (sender._days.all[i].id == "DisabledWeekendsCalendar" + j + "_6") {
sender._days.all[i].disabled = true;
sender._days.all[i].innerHTML =
"<div>" + sender._days.all[i].innerText + "</div>";
}
}
}
}
Try this
<script type="text/javascript">
//disable sunday
function detect_sunday(sender, args) {
if (sender._selectedDate.getDay() == 0) {
sender._selectedDate = new Date();
// set the date back to the current date
sender._textbox.set_Value(sender._selectedDate.format(sender._format));
alert("You can't select sunday!");
}
}
</script>
<asp:CalendarExtender ID="calenderExtender" runat="server" CssClass="cal_theme" TargetControlID="txtCalender"
PopupButtonID="BtnCalender" OnClientDateSelectionChanged="detect_sunday"/>
Using CSS
.DisableWeekends .ajax__calendar_days table tbody tr td:first-child
{
text-decoration: line-through;
color: red;
pointer-events: none;
cursor: default;
}
After that add DisableWeekends class in CalendarExtender controller.

Gtk3 Css button states

I'm using gtk+-3.2.3 with css on Ubuntu natty. In the code below I have a button that starts out with a background color of green with blue text. When I hover over it the background color changes to red but the font color will not change to white as I've specified. Also when pressing and holding the button the background color changes to orange but the font color won't change to cyan that I've specified. Why is this happening? Is this the window manager over-riding my code?
/*Compile with:
gcc -Wall -o cssbutton2 `pkg-config --cflags --libs gtk+-3.0` cssbutton2.c
*/
#include <gtk/gtk.h>
int main(int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *button;
GtkCssProvider *provider;
GdkDisplay *display;
GdkScreen *screen;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 280, 200);
g_signal_connect (GTK_WIDGET (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
button = gtk_button_new_with_label("CssButton");
gtk_widget_set_name (GTK_WIDGET(button), "mybutton");
gtk_widget_set_halign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_valign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_size_request(GTK_WIDGET(button), 200, 120);
gtk_container_add(GTK_CONTAINER(window),button);
provider = gtk_css_provider_new ();
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider),
" GtkWindow {\n"
" background-color: tan;\n"
"}\n"
" GtkButton {\n"
" -GtkWidget-focus-line-width: 0;\n"
" border-radius: 15;\n"
" font: Sans 23;\n"
" color: #00008B;\n"
" background-color: green;\n"
"}\n"
" .button:hover {\n"
" background-color: red;\n"
" color: white;\n"
"}\n"
" .button:hover:active {\n"
" background-color: orange;\n"
" color: cyan;\n"
"}\n", -1, NULL);
g_object_unref (provider);
gtk_widget_show_all(window);
gtk_main();
return(0);
}
I've just tested this on Ubuntu 12.04 (gtk+ 3.4.2) and after adding background-image: none; to the GtkButton style definition, this works as you describe is the desired behavior. Maybe just a bug in GTK that has since been fixed?
you can reference the gtk css style grammar:
https://developer.gnome.org/gtk3/stable/chap-css-overview.html
/*Compile with:
gcc -Wall -o cssbutton2 `pkg-config --cflags --libs gtk+-3.0` cssbutton2.c
*/
#include <gtk/gtk.h>
int main(int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *button;
GtkCssProvider *provider;
GdkDisplay *display;
GdkScreen *screen;
//GtkStyleContext *context;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 280, 200);
gtk_window_set_title(GTK_WINDOW(window),"CSSBUTTON");
g_signal_connect (GTK_WIDGET (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
button = gtk_button_new_with_label("CssButton");
gtk_widget_set_name (GTK_WIDGET(button), "mybutton");
gtk_widget_set_halign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_valign (GTK_WIDGET(button),GTK_ALIGN_CENTER);
gtk_widget_set_size_request(GTK_WIDGET(button), 200, 120);
gtk_container_add(GTK_CONTAINER(window),button);
provider = gtk_css_provider_new ();
display = gdk_display_get_default ();
screen = gdk_display_get_default_screen (display);
// context = gtk_widget_get_style_context(window);
gtk_css_provider_load_from_data (provider,
"*{"
"color:green;"
"font-family:Monospace;"
"border:1px solid;"
" }"
" window {"
" background-color: rgba(50,30,70,100);"
" background-image:none;"
"}"
" button {"
" border-radius: 15px;"
" font: Sans 23;"
" color: #00008B;"
" background-color: green;"
" background-image:none;"
"}"
" button:hover {"
" background-color: red;"
" color: white;"
"}"
" button:hover:active {"
" background-color: orange;"
" color: cyan;"
"}", -1, NULL);
gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER(provider),GTK_STYLE_PROVIDER_PRIORITY_USER);
g_object_unref (provider);
gtk_widget_show_all(window);
gtk_main();
return(0);
}

Resources